fix: update plcc-ng to 2.0.1 #18
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # SPDX-FileCopyrightText: 2026 ourPLCC contributors | |
| # SPDX-License-Identifier: GPL-3.0-or-later | |
| name: CI | |
| on: | |
| pull_request: | |
| branches: [main] | |
| permissions: {} | |
| # Pushing to an open PR leaves the previous run building images that are | |
| # already superseded — two multi-GB builds of the same branch at once. Only | |
| # the newest commit's result matters, so cancel the older run. | |
| concurrency: | |
| group: ci-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # Building both images takes tens of minutes, and most of that is wasted on | |
| # PRs that touch only workflows or docs. Every job below still runs and still | |
| # posts its check — only the expensive steps are guarded. Skipping the jobs | |
| # themselves would leave required status checks unreported and block merges. | |
| changes: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| outputs: | |
| feature: ${{ steps.filter.outputs.feature }} | |
| images: ${{ steps.filter.outputs.images }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # base..head diff needs both endpoints | |
| - name: Detect which parts of the build a change can affect | |
| id: filter | |
| env: | |
| BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| run: | | |
| CHANGED=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA") | |
| echo "Changed files:" | |
| echo "$CHANGED" | |
| # if/else rather than `match ... && VAR=true`: this runs under bash -e, | |
| # where a trailing failed && list would abort the step. | |
| match() { echo "$CHANGED" | grep -qE "$1"; } | |
| # The feature and its own tests. test/plcc-ng/** drives | |
| # `devcontainer features test` and nothing else. | |
| if match '^(src|test/plcc-ng)/|^\.github/workflows/ci\.yml$'; then | |
| FEATURE=true | |
| else | |
| FEATURE=false | |
| fi | |
| # Image contents and how they are built/verified. build-and-test.sh | |
| # copies only test/smoke-test.sh into the image, so the rest of | |
| # test/ cannot change a build result. | |
| if match '^(images|src|scripts)/|^test/smoke-test\.sh$|^\.github/workflows/ci\.yml$'; then | |
| IMAGES=true | |
| else | |
| IMAGES=false | |
| fi | |
| echo "feature=$FEATURE" >> "$GITHUB_OUTPUT" | |
| echo "images=$IMAGES" >> "$GITHUB_OUTPUT" | |
| echo "=> feature tests: $FEATURE | image builds: $IMAGES" | |
| test-feature: | |
| needs: changes | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout | |
| if: needs.changes.outputs.feature == 'true' | |
| uses: actions/checkout@v4 | |
| - name: Install devcontainer CLI | |
| if: needs.changes.outputs.feature == 'true' | |
| run: npm install -g @devcontainers/cli | |
| - name: Test plcc-ng feature | |
| if: needs.changes.outputs.feature == 'true' | |
| run: | | |
| devcontainer features test \ | |
| --project-folder . \ | |
| --features plcc-ng \ | |
| --base-image mcr.microsoft.com/devcontainers/base:ubuntu | |
| build: | |
| needs: [changes, test-feature] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| variant: [plcc-ng, plcc-ng-full] | |
| steps: | |
| - name: Checkout | |
| if: needs.changes.outputs.images == 'true' | |
| uses: actions/checkout@v4 | |
| - name: Free disk space for large image build | |
| if: needs.changes.outputs.images == 'true' && matrix.variant == 'plcc-ng-full' | |
| run: sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/hostedtoolcache/CodeQL | |
| - name: Log in to GHCR | |
| if: needs.changes.outputs.images == 'true' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Install devcontainer CLI | |
| if: needs.changes.outputs.images == 'true' | |
| run: npm install -g @devcontainers/cli | |
| - name: Build image and run smoke test | |
| if: needs.changes.outputs.images == 'true' | |
| run: | | |
| bash scripts/build-and-test.sh "${{ matrix.variant }}" \ | |
| "ghcr.io/ourplcc/devcontainers/${{ matrix.variant }}:pr-${{ github.event.pull_request.number }}" | |
| - name: Push PR image | |
| if: needs.changes.outputs.images == 'true' | |
| run: docker push "ghcr.io/ourplcc/devcontainers/${{ matrix.variant }}:pr-${{ github.event.pull_request.number }}" | |
| comment: | |
| needs: [changes, build] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pull-requests: write | |
| steps: | |
| - name: Comment image tags on PR | |
| # No images were built, so there are no tags to advertise. | |
| if: needs.changes.outputs.images == 'true' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| await github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: [ | |
| '🐳 **PR images built** (amd64 only):', | |
| '- `ghcr.io/ourplcc/devcontainers/plcc-ng:pr-${{ github.event.pull_request.number }}`', | |
| '- `ghcr.io/ourplcc/devcontainers/plcc-ng-full:pr-${{ github.event.pull_request.number }}`', | |
| '', | |
| 'To test, point a devcontainer.json `image` at one of these tags.' | |
| ].join('\n') | |
| }) | |
| # The single check the ruleset should require. | |
| # | |
| # Requiring job names directly is brittle: adding a matrix renames a check | |
| # from `build` to `build (x)`, and a new job is simply never required. Both | |
| # leave the ruleset waiting on a name nothing reports, which hangs the PR on | |
| # "Expected — waiting for status to be reported" with no failure to point at. | |
| # This name never changes, so jobs can come and go without a ruleset edit. | |
| # | |
| # `comment` is deliberately excluded: it only posts image tags, needs | |
| # pull-requests: write (unavailable on fork PRs), and must never block a | |
| # merge. | |
| ci-gate: | |
| needs: [changes, test-feature, build] | |
| # Must run even when a dependency fails — without this the gate is itself | |
| # skipped on failure, reports nothing, and reproduces the exact hang it | |
| # exists to prevent. | |
| if: always() | |
| runs-on: ubuntu-latest | |
| permissions: {} | |
| steps: | |
| - name: Require all CI jobs to have succeeded | |
| env: | |
| CHANGES: ${{ needs.changes.result }} | |
| TEST_FEATURE: ${{ needs.test-feature.result }} | |
| BUILD: ${{ needs.build.result }} | |
| run: | | |
| failed=0 | |
| for entry in "changes=$CHANGES" "test-feature=$TEST_FEATURE" "build=$BUILD"; do | |
| echo "$entry" | |
| # Anything other than success — failure, cancelled, or skipped | |
| # because an upstream job failed — must block the merge. | |
| case "${entry#*=}" in | |
| success) ;; | |
| *) failed=1 ;; | |
| esac | |
| done | |
| if [ "$failed" -ne 0 ]; then | |
| echo "::error::CI did not fully succeed — see the job results above." | |
| exit 1 | |
| fi | |
| echo "All required CI jobs succeeded." |