Compare commits

..

2 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
e25ca83e0f Add documentation about KiCad self-signed certificate issues
Co-authored-by: jbtronics <5410681+jbtronics@users.noreply.github.com>
2025-12-07 18:27:24 +00:00
copilot-swe-agent[bot]
25613eefed Initial plan 2025-12-07 18:23:12 +00:00
9 changed files with 50 additions and 110 deletions

View File

@@ -1,40 +1,6 @@
ARG BASE_IMAGE=debian:bookworm-slim
ARG PHP_VERSION=8.4
# ---
# Build assets stage - runs on native platform (not emulated)
# This stage builds the frontend assets (JavaScript, CSS) using Node.js and Yarn
# The --platform=$BUILDPLATFORM ensures this stage runs on the native build platform (amd64)
# and not under emulation for ARM builds
FROM --platform=$BUILDPLATFORM composer:latest AS composer-deps
WORKDIR /build
# Copy entire project to install dependencies and generate translations
COPY . .
# Install composer dependencies (needed for Symfony UX assets and cache warmup)
RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist --ignore-platform-reqs && \
composer dump-autoload --no-dev --classmap-authoritative && \
php bin/console cache:clear --no-warmup && \
php bin/console cache:warmup
# ---
FROM --platform=$BUILDPLATFORM node:22-bookworm-slim AS assets
WORKDIR /build
# Copy entire project with vendor and generated translations from composer-deps stage
COPY --from=composer-deps /build ./
# Install dependencies and build assets
RUN yarn install --network-timeout 600000 && \
yarn build && \
yarn cache clean
# ---
FROM ${BASE_IMAGE} AS base
ARG PHP_VERSION
@@ -70,7 +36,6 @@ RUN apt-get update && apt-get -y install \
php${PHP_VERSION}-sqlite3 \
php${PHP_VERSION}-mysql \
php${PHP_VERSION}-pgsql \
git \
gpg \
sudo \
&& apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* \
@@ -80,6 +45,15 @@ RUN apt-get update && apt-get -y install \
# delete the "index.html" that installing Apache drops in here
&& rm -rvf /var/www/html/*
# Install node and yarn
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
curl -sL https://deb.nodesource.com/setup_22.x | bash - && \
apt-get update && apt-get install -y \
nodejs \
yarn \
&& apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*
# Install composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
@@ -175,13 +149,14 @@ RUN a2dissite 000-default.conf && \
a2enconf docker-php && \
a2enmod rewrite
# Install composer dependencies for Part-DB
# Install composer and yarn dependencies for Part-DB
USER www-data
RUN composer install -a --no-dev && \
composer clear-cache
# Copy pre-built assets from the assets stage
COPY --from=assets /build/public/build ./public/build
RUN yarn install --network-timeout 600000 && \
yarn build && \
yarn cache clean && \
rm -rf node_modules/
# Use docker env to output logs to stdout
ENV APP_ENV=docker

View File

@@ -1,37 +1,3 @@
# ---
# Build assets stage - runs on native platform (not emulated)
# This stage builds the frontend assets (JavaScript, CSS) using Node.js and Yarn
# The --platform=$BUILDPLATFORM ensures this stage runs on the native build platform (amd64)
# and not under emulation for ARM builds
FROM --platform=$BUILDPLATFORM composer:latest AS composer-deps
WORKDIR /build
# Copy entire project to install dependencies and generate translations
COPY . .
# Install composer dependencies (needed for Symfony UX assets and cache warmup)
RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist --ignore-platform-reqs && \
composer dump-autoload --no-dev --classmap-authoritative && \
php bin/console cache:clear --no-warmup && \
php bin/console cache:warmup
# ---
FROM --platform=$BUILDPLATFORM node:22-bookworm-slim AS assets
WORKDIR /build
# Copy entire project with vendor and generated translations from composer-deps stage
COPY --from=composer-deps /build ./
# Install dependencies and build assets
RUN yarn install --network-timeout 600000 && \
yarn build && \
yarn cache clean
# ---
FROM dunglas/frankenphp:1-php8.4 AS frankenphp_upstream
RUN apt-get update && apt-get -y install \
@@ -47,6 +13,33 @@ RUN apt-get update && apt-get -y install \
zip \
&& apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*;
RUN set -eux; \
# Prepare keyrings directory
mkdir -p /etc/apt/keyrings; \
\
# Import Yarn GPG key
curl -fsSL https://dl.yarnpkg.com/debian/pubkey.gpg \
| tee /etc/apt/keyrings/yarn.gpg >/dev/null; \
chmod 644 /etc/apt/keyrings/yarn.gpg; \
\
# Add Yarn repo with signed-by
echo "deb [signed-by=/etc/apt/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian stable main" \
| tee /etc/apt/sources.list.d/yarn.list; \
\
# Run NodeSource setup script (unchanged)
curl -sL https://deb.nodesource.com/setup_22.x | bash -; \
\
# Install Node.js + Yarn
apt-get update; \
apt-get install -y --no-install-recommends \
nodejs \
yarn; \
\
# Cleanup
apt-get -y autoremove; \
apt-get clean autoclean; \
rm -rf /var/lib/apt/lists/*
# Install PHP
RUN set -eux; \
@@ -97,8 +90,10 @@ RUN set -eux; \
composer run-script --no-dev post-install-cmd; \
chmod +x bin/console; sync;
# Copy pre-built assets from the assets stage
COPY --from=assets /build/public/build ./public/build
RUN yarn install --network-timeout 600000 && \
yarn build && \
yarn cache clean && \
rm -rf node_modules/
# Use docker env to output logs to stdout
ENV APP_ENV=docker

View File

@@ -366,14 +366,6 @@ abstract class BaseAdminController extends AbstractController
}
}
//Count how many actual new entities were created (id is null until persisted)
$created_count = 0;
foreach ($results as $result) {
if (null === $result->getID()) {
$created_count++;
}
}
//Persist valid entities to DB
foreach ($results as $result) {
$em->persist($result);
@@ -381,14 +373,8 @@ abstract class BaseAdminController extends AbstractController
$em->flush();
if (count($results) > 0) {
$this->addFlash('success', t('entity.mass_creation_flash', ['%COUNT%' => $created_count]));
$this->addFlash('success', t('entity.mass_creation_flash', ['%COUNT%' => count($results)]));
}
if (count($errors)) {
//Recreate mass creation form, so we get the updated parent list and empty lines
$mass_creation_form = $this->createForm(MassCreationForm::class, ['entity_class' => $this->entity_class]);
}
}
return $this->render($this->twig_template, [

View File

@@ -169,7 +169,7 @@ abstract class Attachment extends AbstractNamedDBElement
#[ORM\Column(type: Types::STRING, length: 2048, nullable: true)]
#[Groups(['attachment:read'])]
#[ApiProperty(example: 'http://example.com/image.jpg')]
#[Assert\Length(max: 2048)]
#[Assert\Length(2048)]
protected ?string $external_path = null;
/**

View File

@@ -243,14 +243,6 @@ class StructuralDBElementRepository extends AttachmentContainingDBElementReposit
return $result[0];
}
//If the name contains category delimiters like ->, try to find the element by its full path
if (str_contains($name, '->')) {
$tmp = $this->getEntityByPath($name, '->');
if (count($tmp) > 0) {
return $tmp[count($tmp) - 1];
}
}
//If we find nothing, return null
return null;
}

View File

@@ -167,7 +167,7 @@ class EntityImporter
}
//Only return objects once
return array_values(array_unique($valid_entities, SORT_REGULAR));
return array_values(array_unique($valid_entities));
}
/**

View File

@@ -152,7 +152,7 @@ class PKDatastructureImporter
public function importPartCustomStates(array $data): int
{
if (!isset($data['partcustomstate'])) {
return 0; //Not all PartKeepr installations have custom states
throw new \RuntimeException('$data must contain a "partcustomstate" key!');
}
$partCustomStateData = $data['partcustomstate'];

View File

@@ -150,11 +150,6 @@ trait PKImportHelperTrait
$target->addAttachment($attachment);
$this->em->persist($attachment);
//If the attachment is an image, and the target has no master picture yet, set it
if ($attachment->isPicture() && $target->getMasterPictureAttachment() === null) {
$target->setMasterPictureAttachment($attachment);
}
}
$this->em->flush();

View File

@@ -91,10 +91,7 @@ class PKPartImporter
$this->setAssociationField($entity, 'partUnit', MeasurementUnit::class, $part['partUnit_id']);
}
if (isset($part['partCustomState_id'])) {
$this->setAssociationField($entity, 'partCustomState', MeasurementUnit::class,
$part['partCustomState_id']);
}
$this->setAssociationField($entity, 'partCustomState', MeasurementUnit::class, $part['partCustomState_id']);
//Create a part lot to store the stock level and location
$lot = new PartLot();