Skip to content

Add release workflow for macOS universal binary - #4

Merged
rae89 merged 3 commits into
mainfrom
feature/release-workflow
Feb 8, 2026
Merged

Add release workflow for macOS universal binary#4
rae89 merged 3 commits into
mainfrom
feature/release-workflow

Conversation

@rae89

@rae89 rae89 commented Feb 7, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds a workflow_dispatch-triggered GitHub Actions workflow that builds a universal macOS binary (arm64 + x86_64) and publishes it as a GitHub Release
  • Updates README with a "Releasing" section explaining how to trigger the workflow

Test plan

  • Verify workflow YAML is valid by checking the Actions tab after merge
  • Trigger the workflow manually with a test version (e.g. 0.1.0) and confirm the release is created with the correct tarball

🤖 Generated with Claude Code

Adds a manually-triggered workflow that builds an arm64 + x86_64 universal
macOS binary and publishes it as a GitHub Release with auto-generated notes.
Updates README with release instructions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@rae89 rae89 self-assigned this Feb 7, 2026

@FranciscoArredondo FranciscoArredondo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Code Review

Overall, this is a solid addition that automates the release process. However, there are several important improvements needed for production readiness. I've added inline comments for each issue.

@FranciscoArredondo FranciscoArredondo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Code Review

Overall, this is a solid addition that automates the release process. However, there are several important improvements needed for production readiness. I've added inline comments for each issue.

@FranciscoArredondo

Copy link
Copy Markdown
Collaborator

🔴 Critical: Missing error handling in shell commands

Location: .github/workflows/release.yml (lines 41-45, 48, 51-53)

If any command fails, the workflow may continue and produce invalid artifacts.

Recommendation: Add set -euo pipefail to all multi-line shell scripts:

- name: Create universal binary
  run: |
    set -euo pipefail
    lipo -create \
      target/release/pokedex \
      target/x86_64-apple-darwin/release/pokedex \
      -output pokedex

@FranciscoArredondo

Copy link
Copy Markdown
Collaborator

🔴 Critical: Tag creation will fail if tag already exists

Location: .github/workflows/release.yml (lines 50-53)

The workflow will fail if you try to re-run it with the same version, preventing workflow re-execution.

Recommendation: Add a check to handle existing tags:

- name: Create tag
  run: |
    set -euo pipefail
    # Delete tag if it exists (allows re-running workflow)
    git tag -d "v${{ inputs.version }}" 2>/dev/null || true
    git push origin ":refs/tags/v${{ inputs.version }}" 2>/dev/null || true
    git tag "v${{ inputs.version }}"
    git push origin "v${{ inputs.version }}"

@FranciscoArredondo

Copy link
Copy Markdown
Collaborator

🟡 Important: Missing cargo dependency caching

Location: .github/workflows/release.yml (after line 27)

The test workflow caches dependencies, but this workflow doesn't, which will significantly slow down builds.

Recommendation: Add caching after the "Checkout code" step:

- name: Cache cargo dependencies
  uses: actions/cache@v4
  with:
    path: |
      ~/.cargo/bin/
      ~/.cargo/registry/index/
      ~/.cargo/registry/cache/
      ~/.cargo/git/db/
      target/
    key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
    restore-keys: |
      ${{ runner.os }}-cargo-

@FranciscoArredondo

Copy link
Copy Markdown
Collaborator

🟡 Important: No version format validation

Location: .github/workflows/release.yml (after line 27)

The version input accepts any string, which could create invalid tags or cause issues.

Recommendation: Add validation after checkout:

- name: Validate version format
  run: |
    set -euo pipefail
    if ! [[ "${{ inputs.version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
      echo "Error: Version must be in semver format (e.g., 1.0.0)"
      exit 1
    fi

@FranciscoArredondo

Copy link
Copy Markdown
Collaborator

🟡 Important: Missing binary verification

Location: .github/workflows/release.yml (after line 45)

The workflow doesn't verify the binary works before releasing it.

Recommendation: Add verification after creating the universal binary:

- name: Verify binary
  run: |
    set -euo pipefail
    file pokedex
    ./pokedex --help || ./pokedex --version || echo "Binary verification skipped (no --help/--version flags)"

@FranciscoArredondo

Copy link
Copy Markdown
Collaborator

🟢 Minor: Missing cleanup

Location: .github/workflows/release.yml (line 48)

The pokedex binary file remains after creating the archive.

Recommendation: Clean up after packaging:

- name: Package archive
  run: |
    set -euo pipefail
    tar czf pokedex-macos.tar.gz pokedex
    rm pokedex  # Clean up binary file

@FranciscoArredondo

Copy link
Copy Markdown
Collaborator

🟢 Minor: Consider adding explicit contents: read permission

Location: .github/workflows/release.yml (line 23)

For clarity, even though contents: read is typically granted by default.

Recommendation:

permissions:
  contents: write
  contents: read

@FranciscoArredondo

Copy link
Copy Markdown
Collaborator

💡 Suggestion: Version consistency check

Location: .github/workflows/release.yml (after line 27)

Consider adding a check to verify the input version matches Cargo.toml (optional but useful for catching mistakes).

Recommendation:

- name: Check version consistency
  run: |
    set -euo pipefail
    CARGO_VERSION=$(grep '^version = ' Cargo.toml | cut -d'"' -f2)
    INPUT_VERSION="${{ inputs.version }}"
    if [ "$CARGO_VERSION" != "$INPUT_VERSION" ]; then
      echo "Warning: Cargo.toml version ($CARGO_VERSION) differs from input version ($INPUT_VERSION)"
    fi

rae89 and others added 2 commits February 7, 2026 16:24
- Add semver format validation for version input
- Add cargo dependency caching (matching test workflow)
- Add set -euo pipefail to multi-line shell scripts
- Handle existing tags gracefully for workflow re-runs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@rae89

rae89 commented Feb 8, 2026

Copy link
Copy Markdown
Owner Author

Addressed in 2301d09:

  • Error handling: Added set -euo pipefail to all multi-line shell scripts. ✅
  • Existing tag handling: Tags are now deleted before re-creation, allowing safe re-runs. ✅
  • Cargo caching: Added dependency caching matching the test workflow. ✅
  • Version validation: Added semver format check that rejects invalid input early. ✅
  • Binary verification: Skipped — the app is a TUI with no --help/--version flags, so there is nothing meaningful to verify beyond a successful build.
  • Cleanup: Skipped — the runner is ephemeral, so leftover files are discarded automatically.
  • Explicit contents: read: Skipped — duplicate YAML keys are invalid, and write already implies read.
  • Version consistency check: Skipped — the release version may intentionally differ from Cargo.toml (e.g., pre-release builds).

@FranciscoArredondo FranciscoArredondo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Image

@rae89

rae89 commented Feb 8, 2026

Copy link
Copy Markdown
Owner Author

Re: Error handling in shell commands (@FranciscoArredondo)

Added set -euo pipefail to all multi-line shell scripts (create universal binary, create tag). Done in 2301d09.

@rae89

rae89 commented Feb 8, 2026

Copy link
Copy Markdown
Owner Author

Re: Tag creation will fail if tag already exists (@FranciscoArredondo)

Good catch. The tag step now deletes the existing tag (local + remote) before creating it, allowing safe re-runs. Done in 2301d09.

@rae89

rae89 commented Feb 8, 2026

Copy link
Copy Markdown
Owner Author

Re: Missing cargo dependency caching (@FranciscoArredondo)

Added cargo caching matching the test workflow. Done in 2301d09.

@rae89

rae89 commented Feb 8, 2026

Copy link
Copy Markdown
Owner Author

Re: No version format validation (@FranciscoArredondo)

Added a semver regex check as the first step after checkout. Invalid input now fails fast. Done in 2301d09.

@rae89

rae89 commented Feb 8, 2026

Copy link
Copy Markdown
Owner Author

Re: Missing binary verification (@FranciscoArredondo)

Skipping this one — the app is a TUI with no --help or --version flags, so there is nothing meaningful to verify beyond a successful build and lipo exit code.

@rae89

rae89 commented Feb 8, 2026

Copy link
Copy Markdown
Owner Author

Re: Missing cleanup (@FranciscoArredondo)

Skipping — the runner is ephemeral so leftover files are discarded automatically after the job.

@rae89

rae89 commented Feb 8, 2026

Copy link
Copy Markdown
Owner Author

Re: Explicit contents: read permission (@FranciscoArredondo)

Skipping — duplicate YAML keys (contents twice) are invalid. contents: write already implies read access.

@rae89

rae89 commented Feb 8, 2026

Copy link
Copy Markdown
Owner Author

Re: Version consistency check (@FranciscoArredondo)

Skipping — the release version may intentionally differ from Cargo.toml (e.g., the Cargo version stays at 0.1.0 during development while releases use distinct tags).

@rae89
rae89 merged commit da6ca20 into main Feb 8, 2026
1 check passed
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