From e509bc5311d136ebf4a8273dace27b503eb79748 Mon Sep 17 00:00:00 2001 From: GameTec_live Date: Mon, 10 Aug 2026 21:35:10 +0200 Subject: [PATCH] fix: hopefully actually fix CI Turns out that GitHub doesnt give permissions to "on pr" tokens. Split that out into a independent workflow to hopefully resolve that. Again, permissions, pushing to the registry is not allowed. So instead we upload the builder as a artifact and redownload it later. (So the theory) --- .github/workflows/build_firmware.yml | 52 +++++++++++++-- .github/workflows/on_pr.yml | 32 ++-------- .github/workflows/on_pr_comment.yml | 95 ++++++++++++++++++++++++++++ .github/workflows/on_push.yml | 4 ++ .github/workflows/python-checks.yml | 32 ++-------- 5 files changed, 155 insertions(+), 60 deletions(-) create mode 100644 .github/workflows/on_pr_comment.yml diff --git a/.github/workflows/build_firmware.yml b/.github/workflows/build_firmware.yml index 72458a1a..47eacde2 100644 --- a/.github/workflows/build_firmware.yml +++ b/.github/workflows/build_firmware.yml @@ -6,16 +6,21 @@ on: checkout-sha: required: false type: string + publish-builder: + description: Build and publish the firmware builder image + required: false + type: boolean + default: true jobs: build_fw_builder: - name: Build and push fw-builder Docker image + name: Build fw-builder Docker image runs-on: ubuntu-latest permissions: packages: write contents: read outputs: - image_hash: ${{ steps.push.outputs.digest }} + image_ref: ${{ steps.published-image.outputs.image_ref || steps.local-image.outputs.image_ref }} steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 @@ -26,17 +31,20 @@ jobs: fetch-depth: 0 persist-credentials: false - name: ghcr.io login + if: ${{ inputs.publish-builder }} uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract Docker metadata + if: ${{ inputs.publish-builder }} id: meta uses: docker/metadata-action@v6 with: images: ghcr.io/${{ github.repository }}-fw-builder - name: Build and push Docker images + if: ${{ inputs.publish-builder }} id: push uses: docker/build-push-action@v7 with: @@ -46,6 +54,33 @@ jobs: labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max + - name: Build Docker image for this workflow + if: ${{ !inputs.publish-builder }} + uses: docker/build-push-action@v7 + with: + context: firmware + tags: chameleonultra-fw-builder:pr + outputs: type=docker,dest=${{ runner.temp }}/fw-builder.tar + cache-from: type=gha + cache-to: type=gha,mode=max + - name: Upload Docker image + if: ${{ !inputs.publish-builder }} + uses: actions/upload-artifact@v7 + with: + name: firmware-builder-image + path: ${{ runner.temp }}/fw-builder.tar + retention-days: 1 + - name: Use local builder image + if: ${{ !inputs.publish-builder }} + id: local-image + run: echo "image_ref=chameleonultra-fw-builder:pr" >> "$GITHUB_OUTPUT" + - name: Use published builder image + if: ${{ inputs.publish-builder }} + id: published-image + env: + IMAGE: ghcr.io/${{ github.repository }}-fw-builder + DIGEST: ${{ steps.push.outputs.digest }} + run: echo "image_ref=${IMAGE,,}@${DIGEST}" >> "$GITHUB_OUTPUT" build_fw: name: Build firmware runs-on: ubuntu-latest @@ -62,11 +97,18 @@ jobs: ref: ${{ inputs.checkout-sha == null && github.sha || inputs.checkout-sha }} fetch-depth: 0 persist-credentials: false + - name: Download Docker image + if: ${{ !inputs.publish-builder }} + uses: actions/download-artifact@v8 + with: + name: firmware-builder-image + path: ${{ runner.temp }} + - name: Load Docker image + if: ${{ !inputs.publish-builder }} + run: docker load --input "${{ runner.temp }}/fw-builder.tar" - name: Build firmware - env: - repo: ${{ github.repository }} run: | - docker run --rm -v ${PWD}:/workdir -e CURRENT_DEVICE_TYPE=${{ matrix.device_type }} ghcr.io/${repo,,}-fw-builder@${{ needs.build_fw_builder.outputs.image_hash }} firmware/build.sh + docker run --rm -v ${PWD}:/workdir -e CURRENT_DEVICE_TYPE=${{ matrix.device_type }} "${{ needs.build_fw_builder.outputs.image_ref }}" firmware/build.sh - name: Upload built binaries uses: actions/upload-artifact@v7 with: diff --git a/.github/workflows/on_pr.yml b/.github/workflows/on_pr.yml index deae6756..11c09b63 100644 --- a/.github/workflows/on_pr.yml +++ b/.github/workflows/on_pr.yml @@ -2,15 +2,19 @@ name: PR handler on: pull_request: +concurrency: + group: pr-build-${{ github.event.pull_request.number }} + cancel-in-progress: true + jobs: firmware_pipeline: name: Build Firmware permissions: - packages: write contents: read uses: ./.github/workflows/build_firmware.yml with: checkout-sha: "${{ github.event.pull_request.head.sha }}" + publish-builder: false client_pipeline: name: Build Firmware permissions: @@ -18,29 +22,3 @@ jobs: uses: ./.github/workflows/build_client.yml with: checkout-sha: "${{ github.event.pull_request.head.sha }}" - comment: - runs-on: ubuntu-latest - name: Comment on PR - needs: - - firmware_pipeline - - client_pipeline - permissions: - pull-requests: write - steps: - - uses: marocchino/sticky-pull-request-comment@v3 - with: - message: | - # Built artifacts for commit ${{ github.event.pull_request.head.sha }} - - ## Firmware - - - [Ultra APP DFU Package](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/ultra-dfu-app.zip) - - [Ultra binaries](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/ultra-firmware.zip) - - [Lite APP DFU Package](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/lite-dfu-app.zip) - - [Lite binaries](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/lite-firmware.zip) - - ## Client - - - [Linux](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/client-linux.zip) - - [macOS](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/client-macos.zip) - - [Windows](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/client-windows.zip) diff --git a/.github/workflows/on_pr_comment.yml b/.github/workflows/on_pr_comment.yml new file mode 100644 index 00000000..26c5a0bd --- /dev/null +++ b/.github/workflows/on_pr_comment.yml @@ -0,0 +1,95 @@ +name: PR build artifact comment + +on: + workflow_run: + workflows: ["PR handler"] + types: [completed] + +permissions: + pull-requests: write + +jobs: + comment: + name: Comment on PR build result + if: github.event.workflow_run.event == 'pull_request' + runs-on: ubuntu-latest + steps: + - name: Add or update artifact links + uses: actions/github-script@v9 + with: + script: | + const run = context.payload.workflow_run; + let pullNumber = run.pull_requests[0]?.number; + + if (!pullNumber) { + const head = `${run.head_repository.owner.login}:${run.head_branch}`; + const candidates = await github.paginate(github.rest.pulls.list, { + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + head, + per_page: 100, + }); + pullNumber = candidates.find((pull) => pull.head.sha === run.head_sha)?.number; + } + + if (!pullNumber) { + core.setFailed(`Could not find the pull request for workflow run ${run.id}`); + return; + } + + const marker = ''; + const lines = [marker, `# Build result for commit ${run.head_sha}`, '']; + + if (run.conclusion === 'success') { + const baseUrl = `https://nightly.link/${context.repo.owner}/${context.repo.repo}/actions/runs/${run.id}`; + lines.push( + '## Firmware', + '', + `- [Ultra APP DFU Package](${baseUrl}/ultra-dfu-app.zip)`, + `- [Ultra binaries](${baseUrl}/ultra-firmware.zip)`, + `- [Lite APP DFU Package](${baseUrl}/lite-dfu-app.zip)`, + `- [Lite binaries](${baseUrl}/lite-firmware.zip)`, + '', + '## Client', + '', + `- [Linux](${baseUrl}/client-linux.zip)`, + `- [macOS](${baseUrl}/client-macos.zip)`, + `- [Windows](${baseUrl}/client-windows.zip)`, + ); + } else { + lines.push( + `**Status:** ${run.conclusion ?? 'unknown'}`, + '', + `[View workflow run](${run.html_url})`, + ); + } + + const body = lines.join('\n'); + + const comments = await github.paginate(github.rest.issues.listComments, { + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pullNumber, + per_page: 100, + }); + const existing = comments.find((comment) => + comment.user?.login === 'github-actions[bot]' && + (comment.body?.includes(marker) || comment.body?.includes('# Built artifacts for commit ')) + ); + + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pullNumber, + body, + }); + } diff --git a/.github/workflows/on_push.yml b/.github/workflows/on_push.yml index 07d484b8..bce12cd5 100644 --- a/.github/workflows/on_push.yml +++ b/.github/workflows/on_push.yml @@ -3,6 +3,10 @@ name: Push handler on: push: +concurrency: + group: push-${{ github.ref }} + cancel-in-progress: true + jobs: firmware_pipeline: name: Build Firmware diff --git a/.github/workflows/python-checks.yml b/.github/workflows/python-checks.yml index 9d808162..173eaed9 100644 --- a/.github/workflows/python-checks.yml +++ b/.github/workflows/python-checks.yml @@ -37,23 +37,11 @@ jobs: - name: Set up uv uses: astral-sh/setup-uv@v6 - - name: Install dependencies with uv (if lockfile present) - if: ${{ hashFiles('software/uv.lock') != '' }} + - name: Install dependencies with uv run: uv sync --dev - - name: Install tools with pip (fallback) - if: ${{ hashFiles('software/uv.lock') == '' }} - run: | - python -m pip install --upgrade pip - # Try project requirements if present - if [ -f script/requirements.txt ]; then pip install -r script/requirements.txt || true; fi - # Ensure ruff is available - pip install ruff - - name: Ruff check - run: | - set -e - (uv run ruff --version && uv run ruff check .) || ruff check . + run: uv run ruff check . lint-types: runs-on: ubuntu-latest @@ -83,20 +71,8 @@ jobs: - name: Set up uv uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 - - name: Install dependencies with uv (if lockfile present) - if: ${{ hashFiles('software/uv.lock') != '' }} + - name: Install dependencies with uv run: uv sync --dev - - name: Install tools with pip (fallback) - if: ${{ hashFiles('software/uv.lock') == '' }} - run: | - python -m pip install --upgrade pip - # Try project requirements if present - if [ -f script/requirements.txt ]; then pip install -r script/requirements.txt || true; fi - # Ensure pyrefly is available - pip install pyrefly - - name: Pyrefly check - run: | - set -e - (uv run pyrefly --help >/dev/null 2>&1 && uv run pyrefly check) || pyrefly check + run: uv run pyrefly check