Skip to content

chore: add tag-based release flow for v1.3.0 - #27

Merged
swiftlysingh merged 1 commit into
mainfrom
chore/release-v1.3.0
Apr 10, 2026
Merged

chore: add tag-based release flow for v1.3.0#27
swiftlysingh merged 1 commit into
mainfrom
chore/release-v1.3.0

Conversation

@swiftlysingh

@swiftlysingh swiftlysingh commented Apr 10, 2026

Copy link
Copy Markdown
Owner

Summary

  • replace the push-to-main publish workflow with a tag-based release workflow
  • verify pushed tag matches package.json version before publishing
  • publish to npm, create a GitHub release, and update the Homebrew tap formula
  • bump package version to 1.3.0 and update install docs

Validation

  • npm ci
  • npm run build
  • npm run lint
  • npm run build && npm run test:run

Notes

  • NPM_TOKEN exists in the repo secrets
  • HOMEBREW_TAP_GITHUB_TOKEN does not currently exist in the repo secrets, so tagging v1.3.0 now would likely fail during Homebrew tap update

Summary by CodeRabbit

  • New Features

    • Homebrew installation option now available.
  • Documentation

    • Updated installation instructions to include global npm install and Homebrew as alternative installation methods.
  • Chores

    • Version bumped to 1.3.0.
    • Updated release automation workflow.

Copilot AI review requested due to automatic review settings April 10, 2026 20:43
@coderabbitai

coderabbitai Bot commented Apr 10, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The publish workflow triggered automatically on main branch changes has been removed and replaced with a tag-based release workflow. The new workflow publishes to npm and GitHub when version tags are pushed, validates tag matches package.json, and additionally publishes a Homebrew formula to an external tap repository. Documentation and version have been updated accordingly.

Changes

Cohort / File(s) Summary
CI/CD Workflow Restructuring
.github/workflows/publish.yml, .github/workflows/release.yml
Removed automatic push-triggered publish workflow; added new tag-triggered release workflow with version validation, npm publishing, GitHub release creation, and Homebrew formula generation/publishing to external tap repository.
Documentation & Version
README.md, package.json
Updated npm installation instructions to use global install flag; added Homebrew installation option. Version bumped from 1.2.0 to 1.3.0.

Sequence Diagram

sequenceDiagram
    participant Developer
    participant GitHub as GitHub
    participant BuildEnv as Build Environment
    participant NPMRegistry as NPM Registry
    participant GitHubAPI as GitHub API
    participant HomebrewTap as Homebrew Tap Repo

    Developer->>GitHub: Push version tag (v*)
    GitHub->>BuildEnv: Trigger workflow_dispatch
    BuildEnv->>BuildEnv: Resolve release tag from ref
    BuildEnv->>GitHub: Checkout repo at tag
    BuildEnv->>BuildEnv: Setup Node.js 20 + dependencies
    BuildEnv->>BuildEnv: npm ci, npm run build
    BuildEnv->>BuildEnv: npm run test:run, npm run lint
    BuildEnv->>BuildEnv: Validate tag vs package.json version
    alt Validation Failed
        BuildEnv->>Developer: ❌ Job fails
    else Validation Passed
        BuildEnv->>NPMRegistry: npm publish --access public
        BuildEnv->>GitHubAPI: Create GitHub Release with notes
        BuildEnv->>BuildEnv: Download source tarball, compute SHA256
        BuildEnv->>BuildEnv: Generate Homebrew formula
        BuildEnv->>HomebrewTap: Clone tap, commit & push formula
        GitHubAPI->>Developer: ✅ Release created
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Tag-based releases hop with grace,
No more auto-publish to the race,
Validate and build with careful cheer,
Homebrew taps and npm appear,
Version bumped, workflows refined—
A safer release, peace of mind! 🎉

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: replacing the push-to-main publish workflow with a tag-based release flow for version 1.3.0.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/release-v1.3.0

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/release.yml:
- Around line 67-70: Add an early fast-fail gate that checks for required
secrets (at least HOMEBREW_TAP_GITHUB_TOKEN and NPM_TOKEN) before the
irreversible "Publish to npm" step so the workflow fails before any publish
occurs; implement this by inserting a pre-publish step (e.g., "Validate required
secrets" or "Check secrets") that inspects process.env or GitHub secrets and
exits non‑zero if any required secret is missing, and ensure the existing
"Publish to npm" step (name: "Publish to npm") and the later Homebrew update
steps (the Homebrew update block) run only after that validation passes.
- Around line 91-93: The tarball download step uses curl -L which can write an
HTTP error page to release.tar.gz and still succeed; update the curl invocation
that sets TARBALL_URL and writes release.tar.gz to use a failing, verbose form
(e.g., add --fail and --show-error and consider --retry) and ensure the script
checks curl's exit status before computing SHA256 from release.tar.gz so the
checksum step only runs on a successful download; refer to the TARBALL_URL
variable, the curl command that writes release.tar.gz, and the SHA256 checksum
computation to locate where to update.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cda84b85-2fba-464b-83d3-acebe1ed03ba

📥 Commits

Reviewing files that changed from the base of the PR and between 96445b3 and ec034cc.

📒 Files selected for processing (4)
  • .github/workflows/publish.yml
  • .github/workflows/release.yml
  • README.md
  • package.json
💤 Files with no reviewable changes (1)
  • .github/workflows/publish.yml

Comment on lines +67 to +70
- name: Publish to npm
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fail fast on required secrets before irreversible publish.

With Line 67 publishing to npm before Line 117 Homebrew update, a missing HOMEBREW_TAP_GITHUB_TOKEN will fail late and leave a partial release (published npm package + failed workflow). Add an early required-secrets gate before publish/release steps.

Suggested hardening patch
       - name: Verify tag matches package version
         id: version_check
         run: |
@@
           if [ "$ACTUAL_TAG" != "$EXPECTED_TAG" ]; then
             echo "Tag mismatch: expected $EXPECTED_TAG, got $ACTUAL_TAG" >&2
             exit 1
           fi
+
+      - name: Validate required release secrets
+        run: |
+          missing=0
+          if [ -z "${{ secrets.NPM_TOKEN }}" ]; then
+            echo "Missing required secret: NPM_TOKEN" >&2
+            missing=1
+          fi
+          if [ -z "${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}" ]; then
+            echo "Missing required secret: HOMEBREW_TAP_GITHUB_TOKEN" >&2
+            missing=1
+          fi
+          if [ "$missing" -ne 0 ]; then
+            exit 1
+          fi

Also applies to: 117-134

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release.yml around lines 67 - 70, Add an early fast-fail
gate that checks for required secrets (at least HOMEBREW_TAP_GITHUB_TOKEN and
NPM_TOKEN) before the irreversible "Publish to npm" step so the workflow fails
before any publish occurs; implement this by inserting a pre-publish step (e.g.,
"Validate required secrets" or "Check secrets") that inspects process.env or
GitHub secrets and exits non‑zero if any required secret is missing, and ensure
the existing "Publish to npm" step (name: "Publish to npm") and the later
Homebrew update steps (the Homebrew update block) run only after that validation
passes.

Comment on lines +91 to +93
TARBALL_URL="https://github.com/${{ github.repository }}/archive/refs/tags/${{ steps.release_tag.outputs.tag }}.tar.gz"
curl -L "$TARBALL_URL" -o release.tar.gz
SHA256=$(sha256sum release.tar.gz | awk '{print $1}')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Harden tarball download before checksum generation.

Line 92 uses curl -L without --fail; HTTP errors can still produce a file and a checksum, resulting in a broken Homebrew formula.

Suggested robustness patch
-          curl -L "$TARBALL_URL" -o release.tar.gz
+          curl -fL --retry 3 --retry-all-errors --retry-delay 2 "$TARBALL_URL" -o release.tar.gz
+          test -s release.tar.gz
           SHA256=$(sha256sum release.tar.gz | awk '{print $1}')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
TARBALL_URL="https://github.com/${{ github.repository }}/archive/refs/tags/${{ steps.release_tag.outputs.tag }}.tar.gz"
curl -L "$TARBALL_URL" -o release.tar.gz
SHA256=$(sha256sum release.tar.gz | awk '{print $1}')
TARBALL_URL="https://github.com/${{ github.repository }}/archive/refs/tags/${{ steps.release_tag.outputs.tag }}.tar.gz"
curl -fL --retry 3 --retry-all-errors --retry-delay 2 "$TARBALL_URL" -o release.tar.gz
test -s release.tar.gz
SHA256=$(sha256sum release.tar.gz | awk '{print $1}')
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release.yml around lines 91 - 93, The tarball download
step uses curl -L which can write an HTTP error page to release.tar.gz and still
succeed; update the curl invocation that sets TARBALL_URL and writes
release.tar.gz to use a failing, verbose form (e.g., add --fail and --show-error
and consider --retry) and ensure the script checks curl's exit status before
computing SHA256 from release.tar.gz so the checksum step only runs on a
successful download; refer to the TARBALL_URL variable, the curl command that
writes release.tar.gz, and the SHA256 checksum computation to locate where to
update.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR switches publishing from “push to main” to a tag-driven release flow for v1.3.0, ensuring the pushed tag matches package.json before publishing, and extends the release to update a Homebrew tap.

Changes:

  • Add a new tag-triggered GitHub Actions workflow to build/test/lint, publish to npm, create a GitHub release, and update a Homebrew tap formula.
  • Remove the prior push-to-main npm publish workflow.
  • Bump package version to 1.3.0 and update installation docs (npm global + Homebrew).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
README.md Updates install instructions to use global npm install and adds Homebrew install steps.
package.json Bumps version to 1.3.0.
.github/workflows/release.yml Implements tag-based release pipeline, GitHub release creation, and Homebrew tap update.
.github/workflows/publish.yml Removes the previous main-branch publish workflow.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +108 to +113
depends_on "node"

def install
system "npm", "install", *std_npm_args
man1.install "man/excalidraw-cli.1"
end

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

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

The generated Homebrew formula installs the package from the GitHub source tarball but never builds the TypeScript output. This repo does not include a committed dist/ directory, and the CLI bin points to dist/cli.js, so a Homebrew install from source will be missing the executable output and likely fail at runtime. Consider either (a) updating the formula’s install to run the build step (and ensure any build-time deps are available) before installing, or (b) making the formula pull the npm registry tarball (which includes the built dist/).

Copilot uses AI. Check for mistakes.
Comment on lines +91 to +95
TARBALL_URL="https://github.com/${{ github.repository }}/archive/refs/tags/${{ steps.release_tag.outputs.tag }}.tar.gz"
curl -L "$TARBALL_URL" -o release.tar.gz
SHA256=$(sha256sum release.tar.gz | awk '{print $1}')
echo "tarball_url=$TARBALL_URL" >> "$GITHUB_OUTPUT"
echo "sha256=$SHA256" >> "$GITHUB_OUTPUT"

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

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

The SHA256 computation uses curl -L without failing on non-2xx responses. If the tarball URL 404s or GitHub returns an HTML error page, the workflow will still compute a SHA and publish an invalid Homebrew formula. Use curl options that fail on HTTP errors (and optionally validate the downloaded file) so the job stops before updating the tap.

Copilot uses AI. Check for mistakes.
Comment on lines +119 to +125
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"

git clone "https://x-access-token:${HOMEBREW_TAP_GITHUB_TOKEN}@github.com/swiftlysingh/homebrew-tap.git" homebrew-tap
cp Formula/excalidraw-cli.rb homebrew-tap/Formula/excalidraw-cli.rb

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

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

Cloning the tap repo with the token embedded in the URL can leak the credential in some git/curl error output (even if GitHub attempts to mask it). Prefer a pattern that avoids placing secrets in command-line arguments, e.g., using actions/checkout with repository + token, or configuring git credentials via a credential helper/env so the token isn’t part of the clone URL.

Copilot uses AI. Check for mistakes.
@swiftlysingh
swiftlysingh merged commit a26f7dd into main Apr 10, 2026
8 checks passed
@swiftlysingh
swiftlysingh deleted the chore/release-v1.3.0 branch April 10, 2026 21:02
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