Skip to content

Modernize release workflow: gh-release v3, skip redundant builds, and update existing releases safely#2

Merged
axellpadilla merged 5 commits into
mainfrom
copilot/update-gh-release-action
May 9, 2026
Merged

Modernize release workflow: gh-release v3, skip redundant builds, and update existing releases safely#2
axellpadilla merged 5 commits into
mainfrom
copilot/update-gh-release-action

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 9, 2026

This updates the release pipeline to use the latest softprops/action-gh-release and removes unnecessary rebuilds when release assets already exist. It also makes reruns idempotent by updating existing releases instead of failing or duplicating work.

  • Release action upgrade

    • Switched from softprops/action-gh-release@v1.10.0 to @v3.
    • Kept release metadata generation consistent across tag push and manual dispatch flows.
  • Preflight release state detection

    • Added a prepare job that resolves tag/version and queries the GitHub Releases API.
    • Checks for required assets (rust_browser_handler_windows.zip, rust_browser_handler_linux.tar.gz) and emits should_build.
  • Conditional build execution

    • build now runs only when required assets are missing.
    • Prevents re-building already published artifacts for unchanged releases.
  • Idempotent release publishing

    • release job now handles both paths:
      • upload assets when build runs
      • metadata-only update when build is skipped
    • Uses overwrite_files: true to ensure existing releases are updated predictably on reruns.
  • Workflow reliability/readability

    • Uses ${RUNNER_TEMP} for temporary API response files.
    • Tightened release job gating to run only on valid upstream outcomes (!cancelled() + explicit needs result checks).
build:
  needs: prepare
  if: needs.prepare.outputs.should_build == 'true'

- uses: softprops/action-gh-release@v3
  with:
    tag_name: ${{ needs.prepare.outputs.tag }}
    overwrite_files: true

Summary by Sourcery

Modernize the GitHub release workflow to be idempotent, reuse existing artifacts when possible, and safely create or update releases with the latest gh-release action.

Enhancements:

  • Introduce a prepare job that derives tag/version metadata and determines whether a rebuild is needed based on existing release assets.
  • Gate the build job on the prepare job output so artifacts are only rebuilt when required files are missing.
  • Refine the release job to handle both full asset uploads and metadata-only updates while tightening execution conditions for more reliable reruns.
  • Upgrade softprops/action-gh-release from v1 to v3 and centralize the release body content in an environment variable for reuse.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented May 9, 2026

Reviewer's Guide

Refactors the release GitHub Actions workflow to introduce a preparatory release-state detection job, conditionally skip unnecessary builds when release assets already exist, and make the release job idempotent and upgradable via softprops/action-gh-release v3 with consistent metadata handling.

Sequence diagram for idempotent release on workflow_dispatch rerun

sequenceDiagram
  actor Dev as Developer
  participant GA as GitHubActions
  participant Prepare as Job_prepare
  participant GHAPI as GitHubReleasesAPI
  participant Build as Job_build
  participant Release as Job_release
  participant GHRel as softprops_action_gh_release_v3

  Dev->>GA: Trigger workflow_dispatch (version input)

  GA->>Prepare: Start job prepare
  Prepare->>Prepare: Derive tag/version from input
  Prepare->>GHAPI: GET /repos/{repo}/releases/tags/{tag}
  GHAPI-->>Prepare: 200 OK with release JSON (assets complete)
  Prepare->>Prepare: Compute should_build = false
  Prepare-->>GA: Outputs tag, version, should_build=false

  GA->>Build: Evaluate condition needs.prepare.outputs.should_build == 'true'
  Build-->>GA: Condition false, job skipped

  GA->>Release: Start job release
  Release->>Release: Check needs.prepare.result == success
  Release->>Release: Check needs.build.result in {success, skipped}

  alt workflow_dispatch
    Release->>Release: Ensure tag exists (git tag / push)
  end

  Release->>Release: Set RELEASE_BODY env (shared metadata)

  opt should_build == false (metadata-only path)
    Release->>GHRel: Run action-gh-release v3
    activate GHRel
    GHRel->>GHAPI: Update release metadata\n(overwrite_files: true, no new assets)
    GHAPI-->>GHRel: 200 OK
    deactivate GHRel
  end

  Release-->>GA: Job complete (idempotent update)
Loading

File-Level Changes

Change Details Files
Add a prepare job that derives tag/version and decides whether a rebuild is required by querying the GitHub Releases API for required assets.
  • Introduce a prepare job that runs on ubuntu-latest and exposes tag, version, and should_build outputs.
  • Compute tag/version based on whether the workflow was triggered by workflow_dispatch or a tag push.
  • Call the GitHub Releases API with curl, capturing the HTTP status and JSON response into a temp file under RUNNER_TEMP.
  • Run an inline Python script to inspect the existing release assets and set should_build=false when both platform artifacts are already present.
  • Handle non-200/non-404 API responses as hard failures and write TAG, VERSION, and SHOULD_BUILD to GITHUB_OUTPUT.
.github/workflows/release.yml
Gate the build job on the prepare job output so builds only run when required assets are missing.
  • Add needs: prepare to the build job to depend on the prepare phase.
  • Add an if condition checking needs.prepare.outputs.should_build == 'true' to skip the build when assets are already present.
.github/workflows/release.yml
Rework the release job to support both asset-upload and metadata-only update paths while tightening execution conditions.
  • Change release job needs from build to [prepare, build] and add an if condition that requires a successful prepare job and a successful or skipped build while ensuring the workflow is not cancelled.
  • Promote the release body content into a RELEASE_BODY environment variable for reuse across release paths.
  • Add a workflow_dispatch-only step that ensures the release tag exists by creating and pushing it when missing.
  • Restrict artifact download and asset upload steps to run only when should_build is true, avoiding unnecessary downloads on metadata-only updates.
  • Split release creation into two conditional steps: one that uploads artifacts when a build ran and another that performs a metadata-only update when build was skipped.
.github/workflows/release.yml
Upgrade softprops/action-gh-release to v3 and enable safe, idempotent updates with file overwrites.
  • Replace softprops/action-gh-release@v1.10.0 with @V3 for the release steps.
  • Use tag_name and name values sourced from the prepare job outputs instead of recomputing them in the release job.
  • Set overwrite_files: true so reruns update existing release assets and metadata predictably instead of failing or duplicating files.
.github/workflows/release.yml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@axellpadilla axellpadilla marked this pull request as ready for review May 9, 2026 08:39
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path=".github/workflows/release.yml" line_range="35-38" />
<code_context>
+          set -euo pipefail
+          release_json_path="${RUNNER_TEMP}/release.json"
+
+          if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
+            version='${{ github.event.inputs.version }}'
+            tag="v${version}"
+          else
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Guard against empty or malformed `version` when triggered via `workflow_dispatch`.

In the `workflow_dispatch` case we assume `github.event.inputs.version` is non-empty and valid. If it’s missing or not semver-like, we’ll still build `tag="v"` (or another invalid tag) and continue. Please add basic validation (non-empty + simple semver check) and fail fast (`exit 1` with a clear message) when the input is invalid to avoid creating bad tags.

```suggestion
          if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
            version='${{ github.event.inputs.version }}'

            if [[ -z "${version}" ]]; then
              echo "Error: version input is required when triggering via workflow_dispatch." >&2
              exit 1
            fi

            if ! [[ "${version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z]+)*$ ]]; then
              echo "Error: invalid version '${version}' provided via workflow_dispatch; expected semver-like value (e.g. 1.2.3 or 1.2.3-beta.1)." >&2
              exit 1
            fi

            tag="v${version}"
          else
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread .github/workflows/release.yml
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
@axellpadilla axellpadilla merged commit 7a7395f into main May 9, 2026
1 check passed
@axellpadilla axellpadilla deleted the copilot/update-gh-release-action branch May 9, 2026 08:41
@axellpadilla axellpadilla restored the copilot/update-gh-release-action branch May 9, 2026 08:42
@axellpadilla
Copy link
Copy Markdown
Collaborator

@copilot fix Invalid workflow file: .github/workflows/release.yml#L65
You have an error in your yaml syntax on line 65

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants