From b9ad89526aa4183ea280a62efc47da269dbf4b22 Mon Sep 17 00:00:00 2001 From: NellInc Date: Tue, 4 Aug 2026 02:07:20 +0100 Subject: [PATCH 1/3] fix(docker): build each architecture natively --- .github/workflows/docker.yml | 91 +++++++++++++++++------------------- 1 file changed, 43 insertions(+), 48 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 199244a..f1e6dfc 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -13,72 +13,67 @@ on: - 'scada-proxy/**' - '.github/workflows/docker.yml' -env: - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }}/scada-proxy - jobs: build-and-push: name: Build and Push Docker Image - runs-on: ubuntu-latest + uses: docker/github-builder/.github/workflows/build.yml@v1 permissions: contents: read + id-token: write packages: write - security-events: write + with: + output: image + push: ${{ github.event_name != 'pull_request' }} + context: ./scada-proxy + file: ./scada-proxy/Dockerfile + platforms: linux/amd64,linux/arm64 + cache: true + cache-mode: max + sbom: true + set-meta-labels: true + set-meta-annotations: true + meta-images: ghcr.io/${{ github.repository }}/scada-proxy + meta-tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=sha,prefix=sha- + meta-labels: | + org.opencontainers.image.description=AI-Powered Grain Mill Digital Twin Simulator with SCADA Integration + org.opencontainers.image.licenses=MIT + secrets: + registry-auths: | + - registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + github-token: ${{ secrets.GITHUB_TOKEN }} + scan: + name: Scan Docker Image + if: github.event_name != 'pull_request' + needs: build-and-push + runs-on: ubuntu-24.04 + permissions: + contents: read + packages: read + security-events: write steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v4 - - name: Login to Container Registry - if: github.event_name != 'pull_request' uses: docker/login-action@v4 with: - registry: ${{ env.REGISTRY }} + registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract metadata - id: meta - uses: docker/metadata-action@v6 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=sha,prefix=sha- - - - name: Build and push - uses: docker/build-push-action@v7 - with: - context: ./scada-proxy - file: ./scada-proxy/Dockerfile - platforms: linux/amd64,linux/arm64 - push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max - - name: Scan for vulnerabilities - if: github.event_name != 'pull_request' uses: aquasecurity/trivy-action@master with: - # Use first tag from metadata (already lowercased by docker/metadata-action) - image-ref: ${{ fromJSON(steps.meta.outputs.json).tags[0] }} - format: 'sarif' - output: 'trivy-results.sarif' + image-ref: ${{ fromJSON(needs.build-and-push.outputs.meta-json).tags[0] }} + format: sarif + output: trivy-results.sarif - name: Upload Trivy scan results - if: github.event_name != 'pull_request' uses: github/codeql-action/upload-sarif@v4 with: - sarif_file: 'trivy-results.sarif' + sarif_file: trivy-results.sarif From 6dbdef94a330d052902671665c9b1067c93dee56 Mon Sep 17 00:00:00 2001 From: NellInc Date: Tue, 4 Aug 2026 02:09:33 +0100 Subject: [PATCH 2/3] fix(docker): resolve Dockerfile within subdirectory context --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index f1e6dfc..91a730b 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -25,7 +25,7 @@ jobs: output: image push: ${{ github.event_name != 'pull_request' }} context: ./scada-proxy - file: ./scada-proxy/Dockerfile + file: Dockerfile platforms: linux/amd64,linux/arm64 cache: true cache-mode: max From 09c2892738f32a9b00ef184ef526b3c5f2ae5932 Mon Sep 17 00:00:00 2001 From: NellInc Date: Tue, 4 Aug 2026 02:14:00 +0100 Subject: [PATCH 3/3] test(stability): make drift assertion deterministic --- src/stores/__tests__/stabilityStore.test.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/stores/__tests__/stabilityStore.test.ts b/src/stores/__tests__/stabilityStore.test.ts index 981621f..a83bd9c 100644 --- a/src/stores/__tests__/stabilityStore.test.ts +++ b/src/stores/__tests__/stabilityStore.test.ts @@ -706,14 +706,19 @@ describe('StabilityStore', () => { it('should apply small drift to friction sources', () => { const { tickStability } = useStabilityStore.getState(); const initialFriction = { ...useStabilityStore.getState().frictionSources }; - - // Run several ticks to accumulate drift - for (let i = 0; i < 100; i++) { - tickStability(1); + const random = vi.spyOn(Math, 'random').mockReturnValue(0.75); + + try { + // Use a deterministic positive sample so this validates drift rather + // than occasionally failing when independent random walks cancel out. + for (let i = 0; i < 10; i++) { + tickStability(1); + } + } finally { + random.mockRestore(); } const { frictionSources } = useStabilityStore.getState(); - // At least one source should have changed (probabilistic) const changed = Object.keys(frictionSources).some( (key) => Math.abs(frictionSources[key] - initialFriction[key]) > 0.001 );