From 4ed67d01ebacf11e3bf5f13ade8928a9054e4732 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 17 Jan 2026 20:33:44 +0000 Subject: [PATCH 1/8] Initial plan From c73839f3a7ff7c775020bb4488e532c7fee8646c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 17 Jan 2026 20:38:07 +0000 Subject: [PATCH 2/8] Initial plan for merging docker-image steps into release job Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/data/action_pins.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/workflow/data/action_pins.json b/pkg/workflow/data/action_pins.json index 3a943b2f1ce..189d80ee30a 100644 --- a/pkg/workflow/data/action_pins.json +++ b/pkg/workflow/data/action_pins.json @@ -47,8 +47,8 @@ }, "actions/github-script@v7.0.1": { "repo": "actions/github-script", - "version": "v7.1.0", - "sha": "f28e40c7f34bde8b3046d885e986cb6290c5673b" + "version": "v7.0.1", + "sha": "60a0d83039c74a4aee543508d2ffcb1c3799cdea" }, "actions/github-script@v8.0.0": { "repo": "actions/github-script", From 882e00f57b2568e8c44cbf44def9590f42ebbd72 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 17 Jan 2026 20:42:04 +0000 Subject: [PATCH 3/8] Merge docker-image steps into release job - Moved Docker Buildx setup, login, metadata extraction, build/push, SBOM generation, and attestation steps into the release job - Removed the separate docker-image job that was downloading binaries from the release - Docker image now built using locally built binaries from dist/ directory - Updated release job permissions already include packages: write for Docker push Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/release.lock.yml | 157 ++++++++------------------- .github/workflows/release.md | 166 +++++++++-------------------- 2 files changed, 96 insertions(+), 227 deletions(-) diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index fc63203095d..6bbdc3062a0 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -85,7 +85,6 @@ jobs: needs: - activation - config - - docker-image - generate-sbom - release runs-on: ubuntu-latest @@ -1206,117 +1205,6 @@ jobs: path: /tmp/gh-aw/threat-detection/detection.log if-no-files-found: ignore - docker-image: - needs: release - runs-on: ubuntu-latest - permissions: - actions: read - attestations: write - contents: read - id-token: write - packages: write - - steps: - - name: Checkout repository - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - name: Setup Docker Buildx - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - - name: Log in to GitHub Container Registry - uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 - with: - password: ${{ secrets.GITHUB_TOKEN }} - registry: ghcr.io - username: ${{ github.actor }} - - name: Download release artifacts - run: | - echo "Downloading release binaries for release ID: $RELEASE_ID, tag: $RELEASE_TAG" - mkdir -p dist - - # Get the release by ID (works for both draft and published releases) - # Draft releases lose their tag association, so we must query by ID - echo "Fetching release information..." - gh api "/repos/${{ github.repository }}/releases/$RELEASE_ID" \ - --jq '{id, tag_name, name, draft, created_at, asset_count: (.assets | length)}' \ - > /tmp/release_info.json - - echo "Release info:" - cat /tmp/release_info.json - - # Get all linux-* assets from this specific release - echo "" - echo "Fetching linux-* assets..." - gh api "/repos/${{ github.repository }}/releases/$RELEASE_ID" \ - --jq ".assets[] | select(.name | startswith(\"linux-\")) | {name: .name, url: .url, size: .size}" \ - > /tmp/assets.json - - if [ ! -s /tmp/assets.json ]; then - echo "Error: No linux-* assets found in release $RELEASE_TAG (ID: $RELEASE_ID)" - echo "" - echo "Available assets:" - gh api "/repos/${{ github.repository }}/releases/$RELEASE_ID" \ - --jq '.assets[] | .name' - exit 1 - fi - - echo "Found $(jq -s length /tmp/assets.json) linux assets:" - cat /tmp/assets.json - - # Download each asset using authenticated API call - echo "" - while IFS= read -r asset; do - ASSET_NAME=$(echo "$asset" | jq -r '.name') - ASSET_URL=$(echo "$asset" | jq -r '.url') - ASSET_SIZE=$(echo "$asset" | jq -r '.size') - echo "Downloading $ASSET_NAME ($(numfmt --to=iec-i --suffix=B $ASSET_SIZE))..." - gh api "$ASSET_URL" -H "Accept: application/octet-stream" > "dist/$ASSET_NAME" - done < <(jq -c '.' /tmp/assets.json) - - echo "" - echo "Downloaded binaries:" - ls -lh dist/ - echo "✓ Release binaries downloaded successfully" - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_ID: ${{ needs.release.outputs.release_id }} - RELEASE_TAG: ${{ needs.release.outputs.release_tag }} - - name: Extract metadata for Docker - id: meta - uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 - with: - images: ghcr.io/${{ github.repository }} - tags: | - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} - type=sha,format=long - type=raw,value=latest,enable={{is_default_branch}} - - name: Build and push Docker image (amd64) - id: build - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6 - with: - build-args: | - BINARY=dist/linux-amd64 - cache-from: type=gha - cache-to: type=gha,mode=max - context: . - labels: ${{ steps.meta.outputs.labels }} - platforms: linux/amd64 - push: true - tags: ${{ steps.meta.outputs.tags }} - - name: Generate SBOM for Docker image - uses: anchore/sbom-action@0b82b0b1a22399a1c542d4d656f70cd903571b5c # v0 - with: - artifact-name: docker-sbom.spdx.json - format: spdx-json - image: ghcr.io/${{ github.repository }}:${{ needs.release.outputs.release_tag }} - output-file: docker-sbom.spdx.json - - name: Attest Docker image - uses: actions/attest-build-provenance@96b4a1ef7235a096b17240c259729fdd70c83d45 # v2 - with: - push-to-registry: true - subject-digest: ${{ steps.build.outputs.digest }} - subject-name: ghcr.io/${{ github.repository }} - generate-sbom: needs: release runs-on: ubuntu-latest @@ -1471,6 +1359,51 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} RELEASE_TAG: ${{ needs.config.outputs.release_tag }} + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 + - name: Log in to GitHub Container Registry + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 + with: + password: ${{ secrets.GITHUB_TOKEN }} + registry: ghcr.io + username: ${{ github.actor }} + - name: Extract metadata for Docker + id: meta + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha,format=long + type=raw,value=latest,enable={{is_default_branch}} + - name: Build and push Docker image (amd64) + id: build + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6 + with: + build-args: | + BINARY=dist/linux-amd64 + cache-from: type=gha + cache-to: type=gha,mode=max + context: . + labels: ${{ steps.meta.outputs.labels }} + platforms: linux/amd64 + push: true + tags: ${{ steps.meta.outputs.tags }} + - name: Generate SBOM for Docker image + uses: anchore/sbom-action@0b82b0b1a22399a1c542d4d656f70cd903571b5c # v0 + with: + artifact-name: docker-sbom.spdx.json + format: spdx-json + image: ghcr.io/${{ github.repository }}:${{ needs.config.outputs.release_tag }} + output-file: docker-sbom.spdx.json + - name: Attest Docker image + uses: actions/attest-build-provenance@96b4a1ef7235a096b17240c259729fdd70c83d45 # v2 + with: + push-to-registry: true + subject-digest: ${{ steps.build.outputs.digest }} + subject-name: ghcr.io/${{ github.repository }} safe_outputs: needs: diff --git a/.github/workflows/release.md b/.github/workflows/release.md index 4b33d436b5d..bf620e9b8cc 100644 --- a/.github/workflows/release.md +++ b/.github/workflows/release.md @@ -179,6 +179,57 @@ jobs: echo "release_tag=$RELEASE_TAG" >> "$GITHUB_OUTPUT" echo "✓ Release ID: $RELEASE_ID" echo "✓ Release Tag: $RELEASE_TAG" + + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha,format=long + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push Docker image (amd64) + id: build + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + build-args: | + BINARY=dist/linux-amd64 + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Generate SBOM for Docker image + uses: anchore/sbom-action@v0 + with: + image: ghcr.io/${{ github.repository }}:${{ needs.config.outputs.release_tag }} + artifact-name: docker-sbom.spdx.json + output-file: docker-sbom.spdx.json + format: spdx-json + + - name: Attest Docker image + uses: actions/attest-build-provenance@v2 + with: + subject-name: ghcr.io/${{ github.repository }} + subject-digest: ${{ steps.build.outputs.digest }} + push-to-registry: true generate-sbom: needs: ["release"] runs-on: ubuntu-latest @@ -237,122 +288,7 @@ jobs: echo "Attaching SBOM files to release: $RELEASE_TAG" gh release upload "$RELEASE_TAG" sbom.spdx.json sbom.cdx.json --clobber echo "✓ SBOM files attached to release" - docker-image: - needs: ["release"] - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - id-token: write - attestations: write - actions: read - steps: - - name: Checkout repository - uses: actions/checkout@v5 - - - name: Setup Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Log in to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Download release artifacts - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_TAG: ${{ needs.release.outputs.release_tag }} - RELEASE_ID: ${{ needs.release.outputs.release_id }} - run: | - echo "Downloading release binaries for release ID: $RELEASE_ID, tag: $RELEASE_TAG" - mkdir -p dist - - # Get the release by ID (works for both draft and published releases) - # Draft releases lose their tag association, so we must query by ID - echo "Fetching release information..." - gh api "/repos/${{ github.repository }}/releases/$RELEASE_ID" \ - --jq '{id, tag_name, name, draft, created_at, asset_count: (.assets | length)}' \ - > /tmp/release_info.json - - echo "Release info:" - cat /tmp/release_info.json - - # Get all linux-* assets from this specific release - echo "" - echo "Fetching linux-* assets..." - gh api "/repos/${{ github.repository }}/releases/$RELEASE_ID" \ - --jq ".assets[] | select(.name | startswith(\"linux-\")) | {name: .name, url: .url, size: .size}" \ - > /tmp/assets.json - - if [ ! -s /tmp/assets.json ]; then - echo "Error: No linux-* assets found in release $RELEASE_TAG (ID: $RELEASE_ID)" - echo "" - echo "Available assets:" - gh api "/repos/${{ github.repository }}/releases/$RELEASE_ID" \ - --jq '.assets[] | .name' - exit 1 - fi - - echo "Found $(jq -s length /tmp/assets.json) linux assets:" - cat /tmp/assets.json - - # Download each asset using authenticated API call - echo "" - while IFS= read -r asset; do - ASSET_NAME=$(echo "$asset" | jq -r '.name') - ASSET_URL=$(echo "$asset" | jq -r '.url') - ASSET_SIZE=$(echo "$asset" | jq -r '.size') - echo "Downloading $ASSET_NAME ($(numfmt --to=iec-i --suffix=B $ASSET_SIZE))..." - gh api "$ASSET_URL" -H "Accept: application/octet-stream" > "dist/$ASSET_NAME" - done < <(jq -c '.' /tmp/assets.json) - - echo "" - echo "Downloaded binaries:" - ls -lh dist/ - echo "✓ Release binaries downloaded successfully" - - - name: Extract metadata for Docker - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/${{ github.repository }} - tags: | - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} - type=sha,format=long - type=raw,value=latest,enable={{is_default_branch}} - - - name: Build and push Docker image (amd64) - id: build - uses: docker/build-push-action@v6 - with: - context: . - platforms: linux/amd64 - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - build-args: | - BINARY=dist/linux-amd64 - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Generate SBOM for Docker image - uses: anchore/sbom-action@v0 - with: - image: ghcr.io/${{ github.repository }}:${{ needs.release.outputs.release_tag }} - artifact-name: docker-sbom.spdx.json - output-file: docker-sbom.spdx.json - format: spdx-json - - - name: Attest Docker image - uses: actions/attest-build-provenance@v2 - with: - subject-name: ghcr.io/${{ github.repository }} - subject-digest: ${{ steps.build.outputs.digest }} - push-to-registry: true steps: - name: Setup environment and fetch release data env: From 02745e3b0c9c91210f73063be6cbdb84bc224a7f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 17 Jan 2026 21:00:42 +0000 Subject: [PATCH 4/8] Merge generate-sbom steps into release job - Added Go setup and module download steps - Added SBOM generation (SPDX and CycloneDX formats) - Added SBOM secrets audit step - Added SBOM artifact upload and release attachment - Removed separate generate-sbom job - SBOM generation now happens immediately after binary build in same job Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/release.lock.yml | 97 ++++++++++++-------------- .github/workflows/release.md | 108 +++++++++++++---------------- 2 files changed, 93 insertions(+), 112 deletions(-) diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index 6bbdc3062a0..2f1766b69dd 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -85,7 +85,6 @@ jobs: needs: - activation - config - - generate-sbom - release runs-on: ubuntu-latest permissions: @@ -1205,59 +1204,6 @@ jobs: path: /tmp/gh-aw/threat-detection/detection.log if-no-files-found: ignore - generate-sbom: - needs: release - runs-on: ubuntu-latest - permissions: - contents: write - - steps: - - name: Checkout repository - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 - with: - cache: false - go-version-file: go.mod - - name: Download Go modules - run: go mod download - - name: Generate SBOM (SPDX format) - uses: anchore/sbom-action@0b82b0b1a22399a1c542d4d656f70cd903571b5c # v0 - with: - artifact-name: sbom.spdx.json - format: spdx-json - output-file: sbom.spdx.json - - name: Generate SBOM (CycloneDX format) - uses: anchore/sbom-action@0b82b0b1a22399a1c542d4d656f70cd903571b5c # v0 - with: - artifact-name: sbom.cdx.json - format: cyclonedx-json - output-file: sbom.cdx.json - - name: Audit SBOM files for secrets - run: | - echo "Auditing SBOM files for potential secrets..." - if grep -rE "GITHUB_TOKEN|SECRET|PASSWORD|API_KEY|PRIVATE_KEY" sbom.*.json; then - echo "Error: Potential secrets found in SBOM files" - exit 1 - fi - echo "✓ No secrets detected in SBOM files" - - name: Upload SBOM artifacts - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: sbom-artifacts - path: | - sbom.spdx.json - sbom.cdx.json - retention-days: 7 - - name: Attach SBOM to release - run: | - echo "Attaching SBOM files to release: $RELEASE_TAG" - gh release upload "$RELEASE_TAG" sbom.spdx.json sbom.cdx.json --clobber - echo "✓ SBOM files attached to release" - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_TAG: ${{ needs.release.outputs.release_tag }} - pre_activation: runs-on: ubuntu-slim permissions: @@ -1359,6 +1305,49 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} RELEASE_TAG: ${{ needs.config.outputs.release_tag }} + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + cache: false + go-version-file: go.mod + - name: Download Go modules + run: go mod download + - name: Generate SBOM (SPDX format) + uses: anchore/sbom-action@0b82b0b1a22399a1c542d4d656f70cd903571b5c # v0 + with: + artifact-name: sbom.spdx.json + format: spdx-json + output-file: sbom.spdx.json + - name: Generate SBOM (CycloneDX format) + uses: anchore/sbom-action@0b82b0b1a22399a1c542d4d656f70cd903571b5c # v0 + with: + artifact-name: sbom.cdx.json + format: cyclonedx-json + output-file: sbom.cdx.json + - name: Audit SBOM files for secrets + run: | + echo "Auditing SBOM files for potential secrets..." + if grep -rE "GITHUB_TOKEN|SECRET|PASSWORD|API_KEY|PRIVATE_KEY" sbom.*.json; then + echo "Error: Potential secrets found in SBOM files" + exit 1 + fi + echo "✓ No secrets detected in SBOM files" + - name: Upload SBOM artifacts + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + with: + name: sbom-artifacts + path: | + sbom.spdx.json + sbom.cdx.json + retention-days: 7 + - name: Attach SBOM to release + run: | + echo "Attaching SBOM files to release: $RELEASE_TAG" + gh release upload "$RELEASE_TAG" sbom.spdx.json sbom.cdx.json --clobber + echo "✓ SBOM files attached to release" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RELEASE_TAG: ${{ needs.config.outputs.release_tag }} - name: Setup Docker Buildx uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Log in to GitHub Container Registry diff --git a/.github/workflows/release.md b/.github/workflows/release.md index bf620e9b8cc..4d20e91a32a 100644 --- a/.github/workflows/release.md +++ b/.github/workflows/release.md @@ -180,6 +180,56 @@ jobs: echo "✓ Release ID: $RELEASE_ID" echo "✓ Release Tag: $RELEASE_TAG" + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version-file: go.mod + cache: false # Disabled for release security - prevent cache poisoning attacks + + - name: Download Go modules + run: go mod download + + - name: Generate SBOM (SPDX format) + uses: anchore/sbom-action@v0 + with: + artifact-name: sbom.spdx.json + output-file: sbom.spdx.json + format: spdx-json + + - name: Generate SBOM (CycloneDX format) + uses: anchore/sbom-action@v0 + with: + artifact-name: sbom.cdx.json + output-file: sbom.cdx.json + format: cyclonedx-json + + - name: Audit SBOM files for secrets + run: | + echo "Auditing SBOM files for potential secrets..." + if grep -rE "GITHUB_TOKEN|SECRET|PASSWORD|API_KEY|PRIVATE_KEY" sbom.*.json; then + echo "Error: Potential secrets found in SBOM files" + exit 1 + fi + echo "✓ No secrets detected in SBOM files" + + - name: Upload SBOM artifacts + uses: actions/upload-artifact@v6 + with: + name: sbom-artifacts + path: | + sbom.spdx.json + sbom.cdx.json + retention-days: 7 # Minimize exposure window + + - name: Attach SBOM to release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RELEASE_TAG: ${{ needs.config.outputs.release_tag }} + run: | + echo "Attaching SBOM files to release: $RELEASE_TAG" + gh release upload "$RELEASE_TAG" sbom.spdx.json sbom.cdx.json --clobber + echo "✓ SBOM files attached to release" + - name: Setup Docker Buildx uses: docker/setup-buildx-action@v3 @@ -230,64 +280,6 @@ jobs: subject-name: ghcr.io/${{ github.repository }} subject-digest: ${{ steps.build.outputs.digest }} push-to-registry: true - generate-sbom: - needs: ["release"] - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - name: Checkout repository - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 - with: - go-version-file: go.mod - cache: false # Disabled for release security - prevent cache poisoning attacks - - - name: Download Go modules - run: go mod download - - - name: Generate SBOM (SPDX format) - uses: anchore/sbom-action@v0 - with: - artifact-name: sbom.spdx.json - output-file: sbom.spdx.json - format: spdx-json - - - name: Generate SBOM (CycloneDX format) - uses: anchore/sbom-action@v0 - with: - artifact-name: sbom.cdx.json - output-file: sbom.cdx.json - format: cyclonedx-json - - - name: Audit SBOM files for secrets - run: | - echo "Auditing SBOM files for potential secrets..." - if grep -rE "GITHUB_TOKEN|SECRET|PASSWORD|API_KEY|PRIVATE_KEY" sbom.*.json; then - echo "Error: Potential secrets found in SBOM files" - exit 1 - fi - echo "✓ No secrets detected in SBOM files" - - - name: Upload SBOM artifacts - uses: actions/upload-artifact@v6 - with: - name: sbom-artifacts - path: | - sbom.spdx.json - sbom.cdx.json - retention-days: 7 # Minimize exposure window - - - name: Attach SBOM to release - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_TAG: ${{ needs.release.outputs.release_tag }} - run: | - echo "Attaching SBOM files to release: $RELEASE_TAG" - gh release upload "$RELEASE_TAG" sbom.spdx.json sbom.cdx.json --clobber - echo "✓ SBOM files attached to release" steps: - name: Setup environment and fetch release data From ac9d41b811d403661b9f04c065d7eb76e5443b8e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 17 Jan 2026 21:14:40 +0000 Subject: [PATCH 5/8] Simplify release_tag usage by removing redundant output - Removed release_tag output from release job (line 119) - Removed release_tag assignment in get_release step (line 179) - Updated agent job to use needs.config.outputs.release_tag directly (line 288) - Eliminates unnecessary pass-through of release_tag value from config to release to agent - All jobs now consistently reference needs.config.outputs.release_tag Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/release.lock.yml | 4 +--- .github/workflows/release.md | 4 +--- .github/workflows/repository-quality-improver.lock.yml | 1 + 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index 2f1766b69dd..a5acf921e68 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -127,7 +127,7 @@ jobs: - env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} RELEASE_ID: ${{ needs.release.outputs.release_id }} - RELEASE_TAG: ${{ needs.release.outputs.release_tag }} + RELEASE_TAG: ${{ needs.config.outputs.release_tag }} name: Setup environment and fetch release data run: "set -e\nmkdir -p /tmp/gh-aw/release-data\n\n# Use the release ID and tag from the release job\necho \"Release ID from release job: $RELEASE_ID\"\necho \"Release tag from release job: $RELEASE_TAG\"\n\necho \"Processing release: $RELEASE_TAG\"\necho \"RELEASE_TAG=$RELEASE_TAG\" >> \"$GITHUB_ENV\"\n\n# Get the current release information\ngh release view \"$RELEASE_TAG\" --json name,tagName,createdAt,publishedAt,url,body > /tmp/gh-aw/release-data/current_release.json\necho \"✓ Fetched current release information\"\n\n# Get the previous release to determine the range\nPREV_RELEASE_TAG=$(gh release list --limit 2 --json tagName --jq '.[1].tagName // empty')\n\nif [ -z \"$PREV_RELEASE_TAG\" ]; then\n echo \"No previous release found. This appears to be the first release.\"\n echo \"PREV_RELEASE_TAG=\" >> \"$GITHUB_ENV\"\n touch /tmp/gh-aw/release-data/pull_requests.json\n echo \"[]\" > /tmp/gh-aw/release-data/pull_requests.json\nelse\n echo \"Previous release: $PREV_RELEASE_TAG\"\n echo \"PREV_RELEASE_TAG=$PREV_RELEASE_TAG\" >> \"$GITHUB_ENV\"\n \n # Get commits between releases\n echo \"Fetching commits between $PREV_RELEASE_TAG and $RELEASE_TAG...\"\n git fetch --unshallow 2>/dev/null || git fetch --depth=1000\n \n # Get all merged PRs between the two releases\n echo \"Fetching pull requests merged between releases...\"\n PREV_PUBLISHED_AT=$(gh release view \"$PREV_RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n CURR_PUBLISHED_AT=$(gh release view \"$RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n gh pr list \\\n --state merged \\\n --limit 1000 \\\n --json number,title,author,labels,mergedAt,url,body \\\n --jq \"[.[] | select(.mergedAt >= \\\"$PREV_PUBLISHED_AT\\\" and .mergedAt <= \\\"$CURR_PUBLISHED_AT\\\")]\" \\\n > /tmp/gh-aw/release-data/pull_requests.json\n \n PR_COUNT=$(jq length \"/tmp/gh-aw/release-data/pull_requests.json\")\n echo \"✓ Fetched $PR_COUNT pull requests\"\nfi\n\n# Get the CHANGELOG.md content around this version\nif [ -f \"CHANGELOG.md\" ]; then\n cp CHANGELOG.md /tmp/gh-aw/release-data/CHANGELOG.md\n echo \"✓ Copied CHANGELOG.md for reference\"\nfi\n\n# List documentation files for linking\nfind docs -type f -name \"*.md\" 2>/dev/null > /tmp/gh-aw/release-data/docs_files.txt || echo \"No docs directory found\"\n\necho \"✓ Setup complete. Data available in /tmp/gh-aw/release-data/\"" @@ -1247,7 +1247,6 @@ jobs: outputs: release_id: ${{ steps.get_release.outputs.release_id }} - release_tag: ${{ steps.get_release.outputs.release_tag }} steps: - name: Checkout uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 @@ -1299,7 +1298,6 @@ jobs: echo "Getting release ID for tag: $RELEASE_TAG" RELEASE_ID=$(gh release view "$RELEASE_TAG" --json databaseId --jq '.databaseId') echo "release_id=$RELEASE_ID" >> "$GITHUB_OUTPUT" - echo "release_tag=$RELEASE_TAG" >> "$GITHUB_OUTPUT" echo "✓ Release ID: $RELEASE_ID" echo "✓ Release Tag: $RELEASE_TAG" env: diff --git a/.github/workflows/release.md b/.github/workflows/release.md index 4d20e91a32a..60d049d7f0e 100644 --- a/.github/workflows/release.md +++ b/.github/workflows/release.md @@ -116,7 +116,6 @@ jobs: attestations: write outputs: release_id: ${{ steps.get_release.outputs.release_id }} - release_tag: ${{ steps.get_release.outputs.release_tag }} steps: - name: Checkout uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 @@ -176,7 +175,6 @@ jobs: echo "Getting release ID for tag: $RELEASE_TAG" RELEASE_ID=$(gh release view "$RELEASE_TAG" --json databaseId --jq '.databaseId') echo "release_id=$RELEASE_ID" >> "$GITHUB_OUTPUT" - echo "release_tag=$RELEASE_TAG" >> "$GITHUB_OUTPUT" echo "✓ Release ID: $RELEASE_ID" echo "✓ Release Tag: $RELEASE_TAG" @@ -285,7 +283,7 @@ steps: - name: Setup environment and fetch release data env: RELEASE_ID: ${{ needs.release.outputs.release_id }} - RELEASE_TAG: ${{ needs.release.outputs.release_tag }} + RELEASE_TAG: ${{ needs.config.outputs.release_tag }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -e diff --git a/.github/workflows/repository-quality-improver.lock.yml b/.github/workflows/repository-quality-improver.lock.yml index 946467ff667..14695ec6610 100644 --- a/.github/workflows/repository-quality-improver.lock.yml +++ b/.github/workflows/repository-quality-improver.lock.yml @@ -29,6 +29,7 @@ name: "Repository Quality Improvement Agent" "on": schedule: - cron: "0 13 * * 1-5" + # Friendly format: weekly on monday around 15:00 (scattered) workflow_dispatch: permissions: {} From 6078798b49a9ac80c819add588cf1b04fc1c6ccc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 17 Jan 2026 21:22:29 +0000 Subject: [PATCH 6/8] Fix release creation order: build all artifacts before publishing - Removed gh-extension-precompile action (was creating release too early) - Added direct binary build step using scripts/build-release.sh - Removed intermediate "Set draft mode", "Upload checksums", "Attach SBOM" steps - Added final "Create GitHub release" step that creates release with all artifacts - Release now created AFTER binaries, SBOMs, and Docker image are all built - All artifacts attached atomically: dist/*, sbom.spdx.json, sbom.cdx.json - Draft mode handled correctly with --draft flag at creation time Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/release.lock.yml | 85 ++++++++--------- .github/workflows/release.md | 92 ++++++++----------- .../repository-quality-improver.lock.yml | 1 - 3 files changed, 78 insertions(+), 100 deletions(-) diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index a5acf921e68..4c54b3fa5e0 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -1264,50 +1264,18 @@ jobs: echo "✓ Tag created: $RELEASE_TAG" env: RELEASE_TAG: ${{ needs.config.outputs.release_tag }} - - name: Release with gh-extension-precompile - uses: cli/gh-extension-precompile@9e2237c30f869ad3bcaed6a4be2cd43564dd421b # v2.1.0 - with: - build_script_override: scripts/build-release.sh - go_version_file: go.mod - release_tag: ${{ needs.config.outputs.release_tag }} - - name: Set release to draft mode - if: needs.config.outputs.draft_mode == 'true' - run: | - echo "Setting release to draft mode: $RELEASE_TAG" - # Edit the release to set it as draft - gh release edit "$RELEASE_TAG" --draft - echo "✓ Release set to draft mode" - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_TAG: ${{ needs.config.outputs.release_tag }} - - name: Upload checksums file - run: | - if [ -f "dist/checksums.txt" ]; then - echo "Uploading checksums file to release: $RELEASE_TAG" - gh release upload "$RELEASE_TAG" dist/checksums.txt --clobber - echo "✓ Checksums file uploaded to release" - else - echo "Warning: checksums.txt not found in dist/" - fi - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_TAG: ${{ needs.config.outputs.release_tag }} - - name: Get release ID - id: get_release - run: | - echo "Getting release ID for tag: $RELEASE_TAG" - RELEASE_ID=$(gh release view "$RELEASE_TAG" --json databaseId --jq '.databaseId') - echo "release_id=$RELEASE_ID" >> "$GITHUB_OUTPUT" - echo "✓ Release ID: $RELEASE_ID" - echo "✓ Release Tag: $RELEASE_TAG" - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_TAG: ${{ needs.config.outputs.release_tag }} - name: Setup Go uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: cache: false go-version-file: go.mod + - name: Build binaries + run: | + echo "Building binaries for release: $RELEASE_TAG" + bash scripts/build-release.sh "$RELEASE_TAG" + echo "✓ Binaries built successfully" + env: + RELEASE_TAG: ${{ needs.config.outputs.release_tag }} - name: Download Go modules run: go mod download - name: Generate SBOM (SPDX format) @@ -1338,14 +1306,6 @@ jobs: sbom.spdx.json sbom.cdx.json retention-days: 7 - - name: Attach SBOM to release - run: | - echo "Attaching SBOM files to release: $RELEASE_TAG" - gh release upload "$RELEASE_TAG" sbom.spdx.json sbom.cdx.json --clobber - echo "✓ SBOM files attached to release" - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_TAG: ${{ needs.config.outputs.release_tag }} - name: Setup Docker Buildx uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Log in to GitHub Container Registry @@ -1391,6 +1351,37 @@ jobs: push-to-registry: true subject-digest: ${{ steps.build.outputs.digest }} subject-name: ghcr.io/${{ github.repository }} + - name: Create GitHub release + id: get_release + run: | + echo "Creating GitHub release: $RELEASE_TAG" + + # Create release with all binaries + RELEASE_ARGS=() + if [ "$DRAFT_MODE" = "true" ]; then + RELEASE_ARGS+=(--draft) + echo "Creating draft release" + fi + + # Create the release and upload all artifacts + gh release create "$RELEASE_TAG" \ + dist/* \ + sbom.spdx.json \ + sbom.cdx.json \ + --title "$RELEASE_TAG" \ + --generate-notes \ + "${RELEASE_ARGS[@]}" + + # Get release ID + RELEASE_ID=$(gh release view "$RELEASE_TAG" --json databaseId --jq '.databaseId') + echo "release_id=$RELEASE_ID" >> "$GITHUB_OUTPUT" + echo "✓ Release created: $RELEASE_TAG" + echo "✓ Release ID: $RELEASE_ID" + echo "✓ Draft mode: $DRAFT_MODE" + env: + DRAFT_MODE: ${{ needs.config.outputs.draft_mode }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RELEASE_TAG: ${{ needs.config.outputs.release_tag }} safe_outputs: needs: diff --git a/.github/workflows/release.md b/.github/workflows/release.md index 60d049d7f0e..4965d0b12c0 100644 --- a/.github/workflows/release.md +++ b/.github/workflows/release.md @@ -135,55 +135,20 @@ jobs: git push origin "$RELEASE_TAG" echo "✓ Tag created: $RELEASE_TAG" - - name: Release with gh-extension-precompile - uses: cli/gh-extension-precompile@9e2237c30f869ad3bcaed6a4be2cd43564dd421b # v2.1.0 - with: - go_version_file: go.mod - build_script_override: scripts/build-release.sh - release_tag: ${{ needs.config.outputs.release_tag }} - - - name: Set release to draft mode - if: needs.config.outputs.draft_mode == 'true' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_TAG: ${{ needs.config.outputs.release_tag }} - run: | - echo "Setting release to draft mode: $RELEASE_TAG" - # Edit the release to set it as draft - gh release edit "$RELEASE_TAG" --draft - echo "✓ Release set to draft mode" - - - name: Upload checksums file - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_TAG: ${{ needs.config.outputs.release_tag }} - run: | - if [ -f "dist/checksums.txt" ]; then - echo "Uploading checksums file to release: $RELEASE_TAG" - gh release upload "$RELEASE_TAG" dist/checksums.txt --clobber - echo "✓ Checksums file uploaded to release" - else - echo "Warning: checksums.txt not found in dist/" - fi - - - name: Get release ID - id: get_release - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_TAG: ${{ needs.config.outputs.release_tag }} - run: | - echo "Getting release ID for tag: $RELEASE_TAG" - RELEASE_ID=$(gh release view "$RELEASE_TAG" --json databaseId --jq '.databaseId') - echo "release_id=$RELEASE_ID" >> "$GITHUB_OUTPUT" - echo "✓ Release ID: $RELEASE_ID" - echo "✓ Release Tag: $RELEASE_TAG" - - name: Setup Go uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: go.mod cache: false # Disabled for release security - prevent cache poisoning attacks + - name: Build binaries + env: + RELEASE_TAG: ${{ needs.config.outputs.release_tag }} + run: | + echo "Building binaries for release: $RELEASE_TAG" + bash scripts/build-release.sh "$RELEASE_TAG" + echo "✓ Binaries built successfully" + - name: Download Go modules run: go mod download @@ -219,15 +184,6 @@ jobs: sbom.cdx.json retention-days: 7 # Minimize exposure window - - name: Attach SBOM to release - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_TAG: ${{ needs.config.outputs.release_tag }} - run: | - echo "Attaching SBOM files to release: $RELEASE_TAG" - gh release upload "$RELEASE_TAG" sbom.spdx.json sbom.cdx.json --clobber - echo "✓ SBOM files attached to release" - - name: Setup Docker Buildx uses: docker/setup-buildx-action@v3 @@ -279,6 +235,38 @@ jobs: subject-digest: ${{ steps.build.outputs.digest }} push-to-registry: true + - name: Create GitHub release + id: get_release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RELEASE_TAG: ${{ needs.config.outputs.release_tag }} + DRAFT_MODE: ${{ needs.config.outputs.draft_mode }} + run: | + echo "Creating GitHub release: $RELEASE_TAG" + + # Create release with all binaries + RELEASE_ARGS=() + if [ "$DRAFT_MODE" = "true" ]; then + RELEASE_ARGS+=(--draft) + echo "Creating draft release" + fi + + # Create the release and upload all artifacts + gh release create "$RELEASE_TAG" \ + dist/* \ + sbom.spdx.json \ + sbom.cdx.json \ + --title "$RELEASE_TAG" \ + --generate-notes \ + "${RELEASE_ARGS[@]}" + + # Get release ID + RELEASE_ID=$(gh release view "$RELEASE_TAG" --json databaseId --jq '.databaseId') + echo "release_id=$RELEASE_ID" >> "$GITHUB_OUTPUT" + echo "✓ Release created: $RELEASE_TAG" + echo "✓ Release ID: $RELEASE_ID" + echo "✓ Draft mode: $DRAFT_MODE" + steps: - name: Setup environment and fetch release data env: diff --git a/.github/workflows/repository-quality-improver.lock.yml b/.github/workflows/repository-quality-improver.lock.yml index 14695ec6610..946467ff667 100644 --- a/.github/workflows/repository-quality-improver.lock.yml +++ b/.github/workflows/repository-quality-improver.lock.yml @@ -29,7 +29,6 @@ name: "Repository Quality Improvement Agent" "on": schedule: - cron: "0 13 * * 1-5" - # Friendly format: weekly on monday around 15:00 (scattered) workflow_dispatch: permissions: {} From 4dcf315a78f44c510a4e52106de81de059f94beb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 17 Jan 2026 21:28:41 +0000 Subject: [PATCH 7/8] Rewrite compute release configuration step in JavaScript - Replaced bash script with actions/github-script@v7 - Uses GitHub REST API to fetch latest release instead of gh CLI - More concise and readable with JavaScript syntax - Eliminated need for GH_TOKEN env var (provided by github-script) - Same functionality: computes next version for workflow_dispatch or uses tag from push event Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/release.lock.yml | 91 +++++++++++++++------------- .github/workflows/release.md | 97 ++++++++++++++++-------------- 2 files changed, 103 insertions(+), 85 deletions(-) diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index 4c54b3fa5e0..af13779e4c4 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -997,53 +997,62 @@ jobs: persist-credentials: false - name: Compute release configuration id: compute_config - run: | - if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then - # For workflow_dispatch, compute next version based on release type - RELEASE_TYPE="${{ inputs.release_type }}" - DRAFT_MODE="${{ inputs.draft }}" + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + script: | + const isWorkflowDispatch = context.eventName === 'workflow_dispatch'; - echo "Computing next version for release type: $RELEASE_TYPE" + let releaseTag, draftMode; - # Get the latest release tag - LATEST_TAG=$(gh release list --limit 1 --json tagName --jq '.[0].tagName // "v0.0.0"') - echo "Latest release tag: $LATEST_TAG" + if (isWorkflowDispatch) { + const releaseType = context.payload.inputs.release_type; + draftMode = context.payload.inputs.draft; - # Parse version components (strip 'v' prefix) - VERSION="${LATEST_TAG#v}" - IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION" + console.log(`Computing next version for release type: ${releaseType}`); - # Increment based on release type - case "$RELEASE_TYPE" in - major) - MAJOR=$((MAJOR + 1)) - MINOR=0 - PATCH=0 - ;; - minor) - MINOR=$((MINOR + 1)) - PATCH=0 - ;; - patch) - PATCH=$((PATCH + 1)) - ;; - esac + // Get the latest release tag + const { data: releases } = await github.rest.repos.listReleases({ + owner: context.repo.owner, + repo: context.repo.repo, + per_page: 1 + }); - RELEASE_TAG="v${MAJOR}.${MINOR}.${PATCH}" - echo "Computed release tag: $RELEASE_TAG" - else - # For tag push events, use the tag from GITHUB_REF - RELEASE_TAG="${GITHUB_REF#refs/tags/}" - DRAFT_MODE="false" - echo "Using tag from push event: $RELEASE_TAG" - fi + const latestTag = releases[0]?.tag_name || 'v0.0.0'; + console.log(`Latest release tag: ${latestTag}`); - echo "release_tag=$RELEASE_TAG" >> "$GITHUB_OUTPUT" - echo "draft_mode=$DRAFT_MODE" >> "$GITHUB_OUTPUT" - echo "✓ Release tag: $RELEASE_TAG" - echo "✓ Draft mode: $DRAFT_MODE" - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + // Parse version components (strip 'v' prefix) + const version = latestTag.replace(/^v/, ''); + let [major, minor, patch] = version.split('.').map(Number); + + // Increment based on release type + switch (releaseType) { + case 'major': + major += 1; + minor = 0; + patch = 0; + break; + case 'minor': + minor += 1; + patch = 0; + break; + case 'patch': + patch += 1; + break; + } + + releaseTag = `v${major}.${minor}.${patch}`; + console.log(`Computed release tag: ${releaseTag}`); + } else { + // For tag push events, use the tag from GITHUB_REF + releaseTag = context.ref.replace('refs/tags/', ''); + draftMode = 'false'; + console.log(`Using tag from push event: ${releaseTag}`); + } + + core.setOutput('release_tag', releaseTag); + core.setOutput('draft_mode', draftMode); + console.log(`✓ Release tag: ${releaseTag}`); + console.log(`✓ Draft mode: ${draftMode}`); detection: needs: agent diff --git a/.github/workflows/release.md b/.github/workflows/release.md index 4965d0b12c0..94f817d5ef4 100644 --- a/.github/workflows/release.md +++ b/.github/workflows/release.md @@ -59,53 +59,62 @@ jobs: - name: Compute release configuration id: compute_config - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then - # For workflow_dispatch, compute next version based on release type - RELEASE_TYPE="${{ inputs.release_type }}" - DRAFT_MODE="${{ inputs.draft }}" - - echo "Computing next version for release type: $RELEASE_TYPE" - - # Get the latest release tag - LATEST_TAG=$(gh release list --limit 1 --json tagName --jq '.[0].tagName // "v0.0.0"') - echo "Latest release tag: $LATEST_TAG" + uses: actions/github-script@v7 + with: + script: | + const isWorkflowDispatch = context.eventName === 'workflow_dispatch'; - # Parse version components (strip 'v' prefix) - VERSION="${LATEST_TAG#v}" - IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION" + let releaseTag, draftMode; - # Increment based on release type - case "$RELEASE_TYPE" in - major) - MAJOR=$((MAJOR + 1)) - MINOR=0 - PATCH=0 - ;; - minor) - MINOR=$((MINOR + 1)) - PATCH=0 - ;; - patch) - PATCH=$((PATCH + 1)) - ;; - esac + if (isWorkflowDispatch) { + const releaseType = context.payload.inputs.release_type; + draftMode = context.payload.inputs.draft; + + console.log(`Computing next version for release type: ${releaseType}`); + + // Get the latest release tag + const { data: releases } = await github.rest.repos.listReleases({ + owner: context.repo.owner, + repo: context.repo.repo, + per_page: 1 + }); + + const latestTag = releases[0]?.tag_name || 'v0.0.0'; + console.log(`Latest release tag: ${latestTag}`); + + // Parse version components (strip 'v' prefix) + const version = latestTag.replace(/^v/, ''); + let [major, minor, patch] = version.split('.').map(Number); + + // Increment based on release type + switch (releaseType) { + case 'major': + major += 1; + minor = 0; + patch = 0; + break; + case 'minor': + minor += 1; + patch = 0; + break; + case 'patch': + patch += 1; + break; + } + + releaseTag = `v${major}.${minor}.${patch}`; + console.log(`Computed release tag: ${releaseTag}`); + } else { + // For tag push events, use the tag from GITHUB_REF + releaseTag = context.ref.replace('refs/tags/', ''); + draftMode = 'false'; + console.log(`Using tag from push event: ${releaseTag}`); + } - RELEASE_TAG="v${MAJOR}.${MINOR}.${PATCH}" - echo "Computed release tag: $RELEASE_TAG" - else - # For tag push events, use the tag from GITHUB_REF - RELEASE_TAG="${GITHUB_REF#refs/tags/}" - DRAFT_MODE="false" - echo "Using tag from push event: $RELEASE_TAG" - fi - - echo "release_tag=$RELEASE_TAG" >> "$GITHUB_OUTPUT" - echo "draft_mode=$DRAFT_MODE" >> "$GITHUB_OUTPUT" - echo "✓ Release tag: $RELEASE_TAG" - echo "✓ Draft mode: $DRAFT_MODE" + core.setOutput('release_tag', releaseTag); + core.setOutput('draft_mode', draftMode); + console.log(`✓ Release tag: ${releaseTag}`); + console.log(`✓ Draft mode: ${draftMode}`); release: needs: ["activation", "config"] runs-on: ubuntu-latest From 6ca8dc0c20fa3e8bc7478f651438ebb4e7037b71 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 17 Jan 2026 21:39:04 +0000 Subject: [PATCH 8/8] Use release ID to fetch release data and revert action version downgrade - Changed agent setup to use gh api with release ID instead of gh release view with tag - Using release ID works correctly for draft releases (gh release view may fail) - Reverted action_pins.json to restore actions/github-script@v7.1.0 (was incorrectly downgraded to v7.0.1) - Maintains compatibility with draft release workflow Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/aw/actions-lock.json | 5 +++++ .github/workflows/release.lock.yml | 4 ++-- .github/workflows/release.md | 3 ++- pkg/workflow/data/action_pins.json | 4 ++-- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/aw/actions-lock.json b/.github/aw/actions-lock.json index 189d80ee30a..9326fe7c8f3 100644 --- a/.github/aw/actions-lock.json +++ b/.github/aw/actions-lock.json @@ -45,6 +45,11 @@ "version": "v6.0.0", "sha": "018cc2cf5baa6db3ef3c5f8a56943fffe632ef53" }, + "actions/github-script@v7": { + "repo": "actions/github-script", + "version": "v7", + "sha": "f28e40c7f34bde8b3046d885e986cb6290c5673b" + }, "actions/github-script@v7.0.1": { "repo": "actions/github-script", "version": "v7.0.1", diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index af13779e4c4..7551d2250d7 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -129,7 +129,7 @@ jobs: RELEASE_ID: ${{ needs.release.outputs.release_id }} RELEASE_TAG: ${{ needs.config.outputs.release_tag }} name: Setup environment and fetch release data - run: "set -e\nmkdir -p /tmp/gh-aw/release-data\n\n# Use the release ID and tag from the release job\necho \"Release ID from release job: $RELEASE_ID\"\necho \"Release tag from release job: $RELEASE_TAG\"\n\necho \"Processing release: $RELEASE_TAG\"\necho \"RELEASE_TAG=$RELEASE_TAG\" >> \"$GITHUB_ENV\"\n\n# Get the current release information\ngh release view \"$RELEASE_TAG\" --json name,tagName,createdAt,publishedAt,url,body > /tmp/gh-aw/release-data/current_release.json\necho \"✓ Fetched current release information\"\n\n# Get the previous release to determine the range\nPREV_RELEASE_TAG=$(gh release list --limit 2 --json tagName --jq '.[1].tagName // empty')\n\nif [ -z \"$PREV_RELEASE_TAG\" ]; then\n echo \"No previous release found. This appears to be the first release.\"\n echo \"PREV_RELEASE_TAG=\" >> \"$GITHUB_ENV\"\n touch /tmp/gh-aw/release-data/pull_requests.json\n echo \"[]\" > /tmp/gh-aw/release-data/pull_requests.json\nelse\n echo \"Previous release: $PREV_RELEASE_TAG\"\n echo \"PREV_RELEASE_TAG=$PREV_RELEASE_TAG\" >> \"$GITHUB_ENV\"\n \n # Get commits between releases\n echo \"Fetching commits between $PREV_RELEASE_TAG and $RELEASE_TAG...\"\n git fetch --unshallow 2>/dev/null || git fetch --depth=1000\n \n # Get all merged PRs between the two releases\n echo \"Fetching pull requests merged between releases...\"\n PREV_PUBLISHED_AT=$(gh release view \"$PREV_RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n CURR_PUBLISHED_AT=$(gh release view \"$RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n gh pr list \\\n --state merged \\\n --limit 1000 \\\n --json number,title,author,labels,mergedAt,url,body \\\n --jq \"[.[] | select(.mergedAt >= \\\"$PREV_PUBLISHED_AT\\\" and .mergedAt <= \\\"$CURR_PUBLISHED_AT\\\")]\" \\\n > /tmp/gh-aw/release-data/pull_requests.json\n \n PR_COUNT=$(jq length \"/tmp/gh-aw/release-data/pull_requests.json\")\n echo \"✓ Fetched $PR_COUNT pull requests\"\nfi\n\n# Get the CHANGELOG.md content around this version\nif [ -f \"CHANGELOG.md\" ]; then\n cp CHANGELOG.md /tmp/gh-aw/release-data/CHANGELOG.md\n echo \"✓ Copied CHANGELOG.md for reference\"\nfi\n\n# List documentation files for linking\nfind docs -type f -name \"*.md\" 2>/dev/null > /tmp/gh-aw/release-data/docs_files.txt || echo \"No docs directory found\"\n\necho \"✓ Setup complete. Data available in /tmp/gh-aw/release-data/\"" + run: "set -e\nmkdir -p /tmp/gh-aw/release-data\n\n# Use the release ID and tag from the release job\necho \"Release ID from release job: $RELEASE_ID\"\necho \"Release tag from release job: $RELEASE_TAG\"\n\necho \"Processing release: $RELEASE_TAG\"\necho \"RELEASE_TAG=$RELEASE_TAG\" >> \"$GITHUB_ENV\"\n\n# Get the current release information\n# Use release ID to fetch release data (works for draft releases)\ngh api \"/repos/${{ github.repository }}/releases/$RELEASE_ID\" > /tmp/gh-aw/release-data/current_release.json\necho \"✓ Fetched current release information\"\n\n# Get the previous release to determine the range\nPREV_RELEASE_TAG=$(gh release list --limit 2 --json tagName --jq '.[1].tagName // empty')\n\nif [ -z \"$PREV_RELEASE_TAG\" ]; then\n echo \"No previous release found. This appears to be the first release.\"\n echo \"PREV_RELEASE_TAG=\" >> \"$GITHUB_ENV\"\n touch /tmp/gh-aw/release-data/pull_requests.json\n echo \"[]\" > /tmp/gh-aw/release-data/pull_requests.json\nelse\n echo \"Previous release: $PREV_RELEASE_TAG\"\n echo \"PREV_RELEASE_TAG=$PREV_RELEASE_TAG\" >> \"$GITHUB_ENV\"\n \n # Get commits between releases\n echo \"Fetching commits between $PREV_RELEASE_TAG and $RELEASE_TAG...\"\n git fetch --unshallow 2>/dev/null || git fetch --depth=1000\n \n # Get all merged PRs between the two releases\n echo \"Fetching pull requests merged between releases...\"\n PREV_PUBLISHED_AT=$(gh release view \"$PREV_RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n CURR_PUBLISHED_AT=$(gh release view \"$RELEASE_TAG\" --json publishedAt --jq .publishedAt)\n gh pr list \\\n --state merged \\\n --limit 1000 \\\n --json number,title,author,labels,mergedAt,url,body \\\n --jq \"[.[] | select(.mergedAt >= \\\"$PREV_PUBLISHED_AT\\\" and .mergedAt <= \\\"$CURR_PUBLISHED_AT\\\")]\" \\\n > /tmp/gh-aw/release-data/pull_requests.json\n \n PR_COUNT=$(jq length \"/tmp/gh-aw/release-data/pull_requests.json\")\n echo \"✓ Fetched $PR_COUNT pull requests\"\nfi\n\n# Get the CHANGELOG.md content around this version\nif [ -f \"CHANGELOG.md\" ]; then\n cp CHANGELOG.md /tmp/gh-aw/release-data/CHANGELOG.md\n echo \"✓ Copied CHANGELOG.md for reference\"\nfi\n\n# List documentation files for linking\nfind docs -type f -name \"*.md\" 2>/dev/null > /tmp/gh-aw/release-data/docs_files.txt || echo \"No docs directory found\"\n\necho \"✓ Setup complete. Data available in /tmp/gh-aw/release-data/\"" - name: Configure Git credentials env: @@ -997,7 +997,7 @@ jobs: persist-credentials: false - name: Compute release configuration id: compute_config - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 with: script: | const isWorkflowDispatch = context.eventName === 'workflow_dispatch'; diff --git a/.github/workflows/release.md b/.github/workflows/release.md index 94f817d5ef4..b3a2e16addf 100644 --- a/.github/workflows/release.md +++ b/.github/workflows/release.md @@ -294,7 +294,8 @@ steps: echo "RELEASE_TAG=$RELEASE_TAG" >> "$GITHUB_ENV" # Get the current release information - gh release view "$RELEASE_TAG" --json name,tagName,createdAt,publishedAt,url,body > /tmp/gh-aw/release-data/current_release.json + # Use release ID to fetch release data (works for draft releases) + gh api "/repos/${{ github.repository }}/releases/$RELEASE_ID" > /tmp/gh-aw/release-data/current_release.json echo "✓ Fetched current release information" # Get the previous release to determine the range diff --git a/pkg/workflow/data/action_pins.json b/pkg/workflow/data/action_pins.json index 189d80ee30a..3a943b2f1ce 100644 --- a/pkg/workflow/data/action_pins.json +++ b/pkg/workflow/data/action_pins.json @@ -47,8 +47,8 @@ }, "actions/github-script@v7.0.1": { "repo": "actions/github-script", - "version": "v7.0.1", - "sha": "60a0d83039c74a4aee543508d2ffcb1c3799cdea" + "version": "v7.1.0", + "sha": "f28e40c7f34bde8b3046d885e986cb6290c5673b" }, "actions/github-script@v8.0.0": { "repo": "actions/github-script",