From 517939bd6ed9325353d0a5339d522dff304c40d2 Mon Sep 17 00:00:00 2001 From: "Adolfo R. Brandes" Date: Wed, 11 Feb 2026 18:00:40 -0300 Subject: [PATCH] feat: add workflows to publish PR packages for testing When a PR is labeled "package-pr", the CI workflow uploads the npm pack tarball as an artifact. A separate workflow_run-triggered workflow then attaches it to a GitHub release tagged pr- and updates the PR description with the download link. A cleanup workflow deletes the release when the PR is closed. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/ci.yml | 11 ++++ .github/workflows/package-pr-cleanup.yml | 21 +++++++ .github/workflows/package-pr.yml | 74 ++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 .github/workflows/package-pr-cleanup.yml create mode 100644 .github/workflows/package-pr.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7baeabad..4eea75ca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,3 +33,14 @@ jobs: run: npm run test - name: Build Test Site run: cd test-site; npm run build + - name: Save PR metadata + if: contains(github.event.pull_request.labels.*.name, 'package-pr') + run: echo "${{ github.event.pull_request.number }}" > pack/pr-number.txt + - name: Upload package artifact + if: contains(github.event.pull_request.labels.*.name, 'package-pr') + uses: actions/upload-artifact@v4 + with: + name: npm-package + path: | + pack/*.tgz + pack/pr-number.txt diff --git a/.github/workflows/package-pr-cleanup.yml b/.github/workflows/package-pr-cleanup.yml new file mode 100644 index 00000000..dbad20fa --- /dev/null +++ b/.github/workflows/package-pr-cleanup.yml @@ -0,0 +1,21 @@ +name: Package PR Cleanup + +on: + pull_request_target: + types: [closed] + +permissions: + contents: write + +jobs: + cleanup: + if: contains(github.event.pull_request.labels.*.name, 'package-pr') + runs-on: ubuntu-latest + + steps: + - name: Delete PR release + env: + GH_TOKEN: ${{ github.token }} + run: | + TAG="pr-${{ github.event.pull_request.number }}" + gh release delete "$TAG" --repo "${{ github.repository }}" --yes --cleanup-tag || true diff --git a/.github/workflows/package-pr.yml b/.github/workflows/package-pr.yml new file mode 100644 index 00000000..c96c0c94 --- /dev/null +++ b/.github/workflows/package-pr.yml @@ -0,0 +1,74 @@ +name: Package PR + +on: + workflow_run: + workflows: ["Default CI"] + types: [completed] + +permissions: + contents: write + pull-requests: write + actions: read + +jobs: + package: + if: >- + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' && + !startsWith(github.event.workflow_run.head_branch, 'renovate/') + runs-on: ubuntu-latest + + steps: + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: npm-package + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ github.token }} + + - name: Read PR number + id: pr + run: echo "number=$(cat pr-number.txt)" >> "$GITHUB_OUTPUT" + + - name: Upload package to a temporary release + env: + GH_TOKEN: ${{ github.token }} + run: | + TAG="pr-${{ steps.pr.outputs.number }}" + gh release delete "$TAG" --repo "${{ github.repository }}" --yes --cleanup-tag || true + gh release create "$TAG" *.tgz \ + --repo "${{ github.repository }}" \ + --target "${{ github.event.workflow_run.head_sha }}" \ + --prerelease \ + --title "PR #${{ steps.pr.outputs.number }}" \ + --notes "Test package for PR #${{ steps.pr.outputs.number }}" + + - name: Update PR description with package link + env: + GH_TOKEN: ${{ github.token }} + run: | + TAG="pr-${{ steps.pr.outputs.number }}" + ASSET_URL=$(gh release view "$TAG" --repo "${{ github.repository }}" --json assets --jq '.assets[0].url') + BODY=$(gh pr view "${{ steps.pr.outputs.number }}" --repo "${{ github.repository }}" --json body --jq '.body // ""') + MARKER_START="" + MARKER_END="" + PACKAGE_BLOCK="${MARKER_START} + ### Latest PR package + + ${ASSET_URL} + ${MARKER_END}" + + if echo "$BODY" | grep -q "$MARKER_START"; then + BODY=$(echo "$BODY" | awk -v start="$MARKER_START" -v block="$PACKAGE_BLOCK" ' + $0 ~ start { print block; skip=1; next } + skip && // { skip=0; next } + !skip { print } + ') + else + BODY="${BODY} + + ${PACKAGE_BLOCK}" + fi + + echo "$BODY" > /tmp/pr_body.txt + gh pr edit "${{ steps.pr.outputs.number }}" --repo "${{ github.repository }}" --body-file /tmp/pr_body.txt