Skip to content

ci: add a v3 release workflow#3343

Open
talkor wants to merge 1 commit intomasterfrom
ci/v3-release-workflow
Open

ci: add a v3 release workflow#3343
talkor wants to merge 1 commit intomasterfrom
ci/v3-release-workflow

Conversation

@talkor
Copy link
Copy Markdown
Member

@talkor talkor commented Mar 30, 2026

@talkor talkor requested a review from a team as a code owner March 30, 2026 08:34
@qodo-free-for-open-source-projects
Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Add v3 release workflow with build, test, and publish

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add automated v3 release workflow triggered manually from vibe3 branch
• Validate branch, build, test, and publish packages to npm
• Notify Slack team when release process starts
• Generate versions using Lerna with conventional commits
Diagram
flowchart LR
  trigger["Manual Trigger<br/>vibe3 branch"] --> validate["Validate Branch"]
  validate --> notify["Notify Slack"]
  validate --> build["Build & Upload"]
  build --> test["Run Tests"]
  test --> release["Release to npm<br/>with v3 tag"]
Loading

Grey Divider

File Changes

1. .github/workflows/release-v3.yml ⚙️ Configuration changes +85/-0

Complete v3 release workflow with validation and publishing

• New workflow file for v3 release process triggered manually
• Validates execution on vibe3 branch with error handling
• Orchestrates build, test, and release jobs in sequence
• Publishes packages to npm with v3 dist-tag using Lerna
• Sends Slack notification at workflow start with release details

.github/workflows/release-v3.yml


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects
Copy link
Copy Markdown
Contributor

qodo-free-for-open-source-projects bot commented Mar 30, 2026

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Dry-run blocks publishing 🐞 Bug ✓ Correctness
Description
The v3 release workflow runs yarn lerna publish with --dry-run, so it can succeed without
actually publishing any packages to npm. This makes the workflow non-functional as a release
pipeline.
Code

.github/workflows/release-v3.yml[R81-82]

+      - name: Publish to npm with v3 dist-tag
+        run: yarn lerna publish from-package --dist-tag v3 --dry-run -y
Evidence
--dry-run prevents any real npm publication, whereas the repo’s main release workflow performs an
actual publish without --dry-run.

.github/workflows/release-v3.yml[81-82]
.github/workflows/release.yml[80-81]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The v3 release workflow uses `lerna publish ... --dry-run`, which prevents publishing packages to npm.

### Issue Context
This workflow is named and structured as a release workflow, and the existing `release.yml` performs a real publish.

### Fix Focus Areas
- .github/workflows/release-v3.yml[81-82]

### Proposed change
Update the publish step to remove `--dry-run` (keep `--dist-tag v3` if that’s intended), e.g.:
- `yarn lerna publish from-package --dist-tag v3 -y`

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Versioning flag inconsistency 🐞 Bug ✓ Correctness
Description
The v3 workflow’s lerna version command omits --conventional-graduate, unlike the main
release.yml workflow. This can change which packages get promoted to stable during versioning and
lead to unexpected version outputs vs the established release process.
Code

.github/workflows/release-v3.yml[R73-76]

+      - name: Generate new versions
+        run: yarn lerna version --exact --conventional-commits --message "Publish [skip ci]" -y --create-release github
+        env:
+          GH_TOKEN: ${{ secrets.VIBE_GITHUB_TOKEN }}
Evidence
The main release workflow includes --conventional-graduate while the v3 workflow does not; this is
a behavior-affecting divergence in the versioning step.

.github/workflows/release-v3.yml[73-76]
.github/workflows/release.yml[72-75]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`release-v3.yml` runs `yarn lerna version` without the `--conventional-graduate` flag, diverging from the repo’s existing release workflow.

### Issue Context
`release.yml` includes `--conventional-graduate` in the analogous step. If v3 should follow the same promotion/versioning rules, this omission can change which packages are graduated/promoted during a release.

### Fix Focus Areas
- .github/workflows/release-v3.yml[73-76]

### Proposed change
Either:
1) Add `--conventional-graduate` to match `release.yml`, or
2) Add an explicit comment in the workflow explaining why v3 intentionally diverges (to avoid future confusion/mis-releases).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Unpinned third-party action 🐞 Bug ⛨ Security
Description
The workflow references fjogeleit/http-request-action@v1, which is a mutable tag and can change
without review. If the action is compromised/changed upstream, this workflow could execute
unreviewed code (even if only in the Slack notification job).
Code

.github/workflows/release-v3.yml[R23-24]

+      - name: Send Slack notification
+        uses: fjogeleit/http-request-action@v1
Evidence
The Slack notification step uses a third-party GitHub Action pinned to a moving tag (@v1) rather
than an immutable commit SHA.

.github/workflows/release-v3.yml[23-24]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The workflow uses a third-party action pinned to a mutable version tag (`@v1`), which increases supply-chain risk.

### Issue Context
This specific step is only used for Slack notifications, so the blast radius is smaller than build/publish steps, but pinning is still a recommended hardening practice.

### Fix Focus Areas
- .github/workflows/release-v3.yml[23-24]

### Proposed change
Replace `fjogeleit/http-request-action@v1` with a commit-SHA-pinned reference (and optionally add a comment with the human-readable version), e.g.:
- `fjogeleit/http-request-action@<full_sha>`

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines +8 to +17
name: Validate Branch
runs-on: ubuntu-latest
steps:
- name: Ensure running on vibe3
if: github.ref != 'refs/heads/vibe3'
run: |
echo "::error::Release v3 workflow must be triggered from the vibe3 branch. Current branch: ${{ github.ref }}"
exit 1

notify-release-start:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}

Copilot Autofix

AI 3 days ago

In general, this issue is fixed by explicitly declaring a minimal permissions: block for the workflow or for individual jobs, instead of inheriting the repository/org defaults. For most workflows that only need to read repository contents, contents: read is a safe baseline; jobs that create releases or otherwise write to the repo can be given the narrower contents: write or specific scopes as needed.

For this workflow, the best minimally-invasive fix is:

  • Add a workflow-level permissions: block setting contents: read so that all jobs default to read-only access.
  • Override permissions for the release job, which creates GitHub releases and likely needs to write release data and possibly tags, by setting contents: write. This grants that job the rights it needs while keeping others restricted.
  • Place the workflow-level permissions: block after name: and before on: for clarity and to follow common conventions.

No extra imports or external libraries are needed; this is purely a YAML configuration change inside .github/workflows/release-v3.yml.

Suggested changeset 1
.github/workflows/release-v3.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/release-v3.yml b/.github/workflows/release-v3.yml
--- a/.github/workflows/release-v3.yml
+++ b/.github/workflows/release-v3.yml
@@ -1,5 +1,8 @@
 name: Release v3 version
 
+permissions:
+  contents: read
+
 on:
   workflow_dispatch:
 
@@ -57,6 +60,8 @@
     needs: [build, test]
     if: ${{ needs.build.outputs.has_changes == 'true' }}
     runs-on: ubuntu-latest
+    permissions:
+      contents: write
     env:
       NODE_AUTH_TOKEN: ${{ secrets.npm_token }}
     steps:
EOF
@@ -1,5 +1,8 @@
name: Release v3 version

permissions:
contents: read

on:
workflow_dispatch:

@@ -57,6 +60,8 @@
needs: [build, test]
if: ${{ needs.build.outputs.has_changes == 'true' }}
runs-on: ubuntu-latest
permissions:
contents: write
env:
NODE_AUTH_TOKEN: ${{ secrets.npm_token }}
steps:
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +18 to +39
name: Notify Slack - Release Started
needs: validate-branch
runs-on: ubuntu-latest
continue-on-error: true
steps:
- name: Send Slack notification
uses: fjogeleit/http-request-action@v1
with:
url: ${{ secrets.SLACK_DEV_TEAM_WEBHOOK_URL }}
method: "POST"
contentType: "application/json"
data: |
{
"event": "v3_release_started",
"actor": "${{ github.actor }}",
"commit_id": "${{ github.sha }}",
"workflow": "${{ github.workflow }}",
"run_url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"commit_url": "${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}"
}

build:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}

Copilot Autofix

AI 3 days ago

In general, the fix is to explicitly define permissions: for the workflow or for each job, so that the GITHUB_TOKEN has only the privileges required. For most jobs that only need to read repository metadata, contents: read is sufficient; for jobs that need to create releases, tags, or manipulate repository contents, contents: write (and any other specific scopes) should be set explicitly. Defining permissions: at the workflow root applies to all jobs unless overridden.

For this specific file, the simplest least-disruptive fix is:

  • Add a root-level permissions: block limiting defaults for all jobs to read-only: contents: read.
  • For the release job, which runs yarn lerna version ... --create-release github using GH_TOKEN: ${{ secrets.VIBE_GITHUB_TOKEN }}, the GITHUB_TOKEN is not directly used; however, release/tag creation commonly requires repository write permissions. To avoid inadvertently breaking behavior if any step or composite action in .github/actions/* relies on GITHUB_TOKEN, we should grant contents: write to that particular job.
  • The other jobs (validate-branch, notify-release-start, build, test) only need to read repository information and secrets, so they can safely inherit contents: read from the root.

Concretely:

  • In .github/workflows/release-v3.yml, add at the top level (e.g., after on:) a permissions: contents: read block.
  • Inside the release: job definition, add a permissions: block with contents: write.

No additional imports or external packages are needed; this is configuration-only.

Suggested changeset 1
.github/workflows/release-v3.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/release-v3.yml b/.github/workflows/release-v3.yml
--- a/.github/workflows/release-v3.yml
+++ b/.github/workflows/release-v3.yml
@@ -3,6 +3,9 @@
 on:
   workflow_dispatch:
 
+permissions:
+  contents: read
+
 jobs:
   validate-branch:
     name: Validate Branch
@@ -57,6 +60,8 @@
     needs: [build, test]
     if: ${{ needs.build.outputs.has_changes == 'true' }}
     runs-on: ubuntu-latest
+    permissions:
+      contents: write
     env:
       NODE_AUTH_TOKEN: ${{ secrets.npm_token }}
     steps:
EOF
@@ -3,6 +3,9 @@
on:
workflow_dispatch:

permissions:
contents: read

jobs:
validate-branch:
name: Validate Branch
@@ -57,6 +60,8 @@
needs: [build, test]
if: ${{ needs.build.outputs.has_changes == 'true' }}
runs-on: ubuntu-latest
permissions:
contents: write
env:
NODE_AUTH_TOKEN: ${{ secrets.npm_token }}
steps:
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +40 to +46
name: Build
needs: validate-branch
uses: ./.github/workflows/build-and-upload.yml
secrets:
npm_token: ${{ secrets.npm_token }}

test:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}

Copilot Autofix

AI 3 days ago

In general, the fix is to explicitly declare permissions for the GITHUB_TOKEN, applying the principle of least privilege. Start with a restrictive default (typically contents: read) at the workflow root so it applies to all jobs, then override per job if a broader permission is actually required (for example, contents: write for a job that creates GitHub releases).

For this specific workflow in .github/workflows/release-v3.yml, the best targeted fix without changing functionality is:

  • Add a workflow-level permissions block under name: Release v3 version that sets minimal read-only permissions, e.g.:
permissions:
  contents: read

This will apply to all jobs by default.

  • The release job runs yarn lerna version ... --create-release github, which uses the GITHUB_TOKEN to create GitHub releases (write to repository contents/releases). To preserve current behavior, we should grant contents: write to that job specifically by adding a permissions block under release:. This job-specific block overrides the workflow default only for that job; other jobs remain at contents: read.

No imports or additional methods are required, as this is pure YAML configuration. The main changes are: (1) insert a permissions: section after the workflow name:; (2) insert a permissions: section under the release job, before needs:.

Suggested changeset 1
.github/workflows/release-v3.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/release-v3.yml b/.github/workflows/release-v3.yml
--- a/.github/workflows/release-v3.yml
+++ b/.github/workflows/release-v3.yml
@@ -1,4 +1,6 @@
 name: Release v3 version
+permissions:
+  contents: read
 
 on:
   workflow_dispatch:
@@ -54,6 +56,8 @@
 
   release:
     name: Release
+    permissions:
+      contents: write
     needs: [build, test]
     if: ${{ needs.build.outputs.has_changes == 'true' }}
     runs-on: ubuntu-latest
EOF
@@ -1,4 +1,6 @@
name: Release v3 version
permissions:
contents: read

on:
workflow_dispatch:
@@ -54,6 +56,8 @@

release:
name: Release
permissions:
contents: write
needs: [build, test]
if: ${{ needs.build.outputs.has_changes == 'true' }}
runs-on: ubuntu-latest
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +47 to +55
name: Test
needs: build
uses: ./.github/workflows/test.yml
with:
has_changes: ${{ needs.build.outputs.has_changes }}
secrets:
npm_token: ${{ secrets.npm_token }}

release:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}

Copilot Autofix

AI 3 days ago

In general, the fix is to add an explicit permissions block that follows least‑privilege principles. We can define restrictive default permissions at the top level of the workflow (permissions: under the workflow name / on: block) so they apply to all jobs, and then override them for specific jobs (here, release) that require additional write permissions.

For this workflow, a good, non‑breaking approach is:

  • Add a workflow‑level permissions block with read‑only access to contents and packages, which is sufficient for jobs that only read the repo or artifacts (like validate-branch, notify-release-start, build, and test).
  • Add a job‑level permissions block to the release job that grants the write scopes it clearly needs. Because release runs yarn lerna version --create-release github and uses a PAT‑like secret (VIBE_GITHUB_TOKEN) for releases/tags, it almost certainly needs at least:
    • contents: write (tags/commits/releases)
    • pull-requests: write if it interacts with PRs (conventional release flows often do)
    • Potentially issues: write if it posts to issues; since we don’t see that here, we can omit it to stay minimal.
  • The test job is the one flagged but is implemented as a reusable workflow call; it likely only needs read access, which will be provided by the workflow‑level permissions.

Concretely:

  • Edit .github/workflows/release-v3.yml.

  • After the on: section, insert:

    permissions:
      contents: read
      packages: read
  • Inside the release job definition, add a permissions: block that overrides the default:

    permissions:
      contents: write
      pull-requests: write

No imports or external libraries are involved; we only adjust YAML configuration inside this workflow file.

Suggested changeset 1
.github/workflows/release-v3.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/release-v3.yml b/.github/workflows/release-v3.yml
--- a/.github/workflows/release-v3.yml
+++ b/.github/workflows/release-v3.yml
@@ -3,6 +3,10 @@
 on:
   workflow_dispatch:
 
+permissions:
+  contents: read
+  packages: read
+
 jobs:
   validate-branch:
     name: Validate Branch
@@ -57,6 +61,9 @@
     needs: [build, test]
     if: ${{ needs.build.outputs.has_changes == 'true' }}
     runs-on: ubuntu-latest
+    permissions:
+      contents: write
+      pull-requests: write
     env:
       NODE_AUTH_TOKEN: ${{ secrets.npm_token }}
     steps:
EOF
@@ -3,6 +3,10 @@
on:
workflow_dispatch:

permissions:
contents: read
packages: read

jobs:
validate-branch:
name: Validate Branch
@@ -57,6 +61,9 @@
needs: [build, test]
if: ${{ needs.build.outputs.has_changes == 'true' }}
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
env:
NODE_AUTH_TOKEN: ${{ secrets.npm_token }}
steps:
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +56 to +85
name: Release
needs: [build, test]
if: ${{ needs.build.outputs.has_changes == 'true' }}
runs-on: ubuntu-latest
env:
NODE_AUTH_TOKEN: ${{ secrets.npm_token }}
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.VIBE_GITHUB_TOKEN }}
fetch-depth: 0
- name: Run Setup
uses: ./.github/actions/setup
with:
npm_token: ${{ secrets.npm_token }}
- uses: ./.github/actions/git-creds
- uses: ./.github/actions/download-builds
- name: Generate new versions
run: yarn lerna version --exact --conventional-commits --message "Publish [skip ci]" -y --create-release github
env:
GH_TOKEN: ${{ secrets.VIBE_GITHUB_TOKEN }}
- run: yarn config set registry https://registry.npmjs.org/
- name: Setup .npmrc for publish
id: setup-npmrc
run: echo "//registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN" > .npmrc
- name: Publish to npm with v3 dist-tag
run: yarn lerna publish from-package --dist-tag v3 --dry-run -y
- name: Remove .npmrc
if: steps.setup-npmrc.outcome == 'success'
run: rm .npmrc

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 3 days ago

In general, the fix is to add an explicit permissions block that grants the least privilege required to run this workflow. Since this workflow mostly uses a custom VIBE_GITHUB_TOKEN secret and is triggered manually (workflow_dispatch), a conservative root-level permissions block of contents: read is an appropriate baseline. If specific jobs (like release) require additional write permissions for GITHUB_TOKEN, they can override or extend permissions at the job level; however, based on the visible snippet, release relies on VIBE_GITHUB_TOKEN for tag/release operations, so contents: read at the workflow level should not change functionality.

Concretely, edit .github/workflows/release-v3.yml to add a root-level permissions: section between the on: block and the jobs: block. This will apply to all jobs in this workflow that do not define their own permissions. The new block should be:

permissions:
  contents: read

No imports or new methods are needed; this is purely a YAML configuration change to the workflow file.

Suggested changeset 1
.github/workflows/release-v3.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/release-v3.yml b/.github/workflows/release-v3.yml
--- a/.github/workflows/release-v3.yml
+++ b/.github/workflows/release-v3.yml
@@ -3,6 +3,9 @@
 on:
   workflow_dispatch:
 
+permissions:
+  contents: read
+
 jobs:
   validate-branch:
     name: Validate Branch
EOF
@@ -3,6 +3,9 @@
on:
workflow_dispatch:

permissions:
contents: read

jobs:
validate-branch:
name: Validate Branch
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +81 to +82
- name: Publish to npm with v3 dist-tag
run: yarn lerna publish from-package --dist-tag v3 --dry-run -y
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.

Action required

1. Dry-run blocks publishing 🐞 Bug ✓ Correctness

The v3 release workflow runs yarn lerna publish with --dry-run, so it can succeed without
actually publishing any packages to npm. This makes the workflow non-functional as a release
pipeline.
Agent Prompt
### Issue description
The v3 release workflow uses `lerna publish ... --dry-run`, which prevents publishing packages to npm.

### Issue Context
This workflow is named and structured as a release workflow, and the existing `release.yml` performs a real publish.

### Fix Focus Areas
- .github/workflows/release-v3.yml[81-82]

### Proposed change
Update the publish step to remove `--dry-run` (keep `--dist-tag v3` if that’s intended), e.g.:
- `yarn lerna publish from-package --dist-tag v3 -y`

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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