Skip to content

ci: grant issues/PR write to fix semantic-release success step#155

Merged
filiphric merged 1 commit into
mainfrom
ci/fix-semantic-release-permissions
Jun 28, 2026
Merged

ci: grant issues/PR write to fix semantic-release success step#155
filiphric merged 1 commit into
mainfrom
ci/fix-semantic-release-permissions

Conversation

@filiphric

Copy link
Copy Markdown
Owner

Context

In the run for #154 on `main`, trusted publishing worked end to end — 2.12.0 published to npm with provenance, git tag and GitHub release created. But the job still exited non-zero.

What failed

`@semantic-release/github`'s post-release `success` hook (which comments on the issues/PRs included in a release, e.g. #151) got:

```
HttpError: Resource not accessible by integration
PATCH /repos//issues/151 → 403
x-accepted-github-permissions: issues=write; pull_requests=write
```

Root cause

Adding an explicit `permissions:` block in #154 restricts `GITHUB_TOKEN` to only the listed scopes. We listed `contents` + `id-token` but omitted `issues` / `pull-requests`, so the release commenting was denied.

Fix

Add `issues: write` and `pull-requests: write` to the job's permissions block. No effect on the (already working) OIDC publish path.

The explicit permissions block restricts GITHUB_TOKEN to only the listed
scopes. semantic-release's @semantic-release/github success hook comments
on released issues/PRs, which needs issues:write and pull-requests:write.
Without them the publish succeeds but the job exits 403 (Resource not
accessible by integration).
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 28, 2026

Copy link
Copy Markdown

Code Review by Qodo

Grey Divider

New Review Started

This review has been superseded by a new analysis

Grey Divider

Qodo Logo

@qodo-for-filiphric

qodo-for-filiphric Bot commented Jun 28, 2026

Copy link
Copy Markdown

PR Summary by Qodo

CI: add issues/PR write permissions for semantic-release success hook
⚙️ Configuration changes 🕐 Less than 10 minutes

Grey Divider

Description

• Grant GITHUB_TOKEN write access to issues and pull requests in CI.
• Fix semantic-release GitHub success hook 403 while keeping OIDC publishing unchanged.
• Ensure release job exits successfully after tagging, releasing, and commenting.
Diagram

graph TD
  A["GitHub Actions job"] --> B["Job permissions"] --> C["semantic-release"]
  C --> D["GitHub Issues/PRs"]
  C --> E["Tags & Release"]
  C --> F["npm publish (OIDC)"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Disable semantic-release success comments
  • ➕ Avoids needing issues/pull-requests write permissions
  • ➕ Reduces token scope surface area
  • ➖ Loses automated release cross-linking/commenting on issues/PRs
  • ➖ May reduce release traceability for contributors
2. Use a dedicated PAT for commenting
  • ➕ Keeps default GITHUB_TOKEN tightly scoped
  • ➕ Can control permissions independently of the workflow token
  • ➖ Introduces long-lived secret management and rotation burden
  • ➖ Often discouraged vs GITHUB_TOKEN for GitHub-native automation

Recommendation: Proceed with the PR’s approach: explicitly granting issues: write and pull-requests: write to the job is the simplest and most idiomatic fix for @semantic-release/github success-hook commenting. It resolves the 403 without introducing new secrets and does not affect the already-working OIDC npm publish flow.

Files changed (1) +4 / -2

Other (1) +4 / -2
tests.ymlGrant issues and pull-requests write permissions to semantic-release +4/-2

Grant issues and pull-requests write permissions to semantic-release

• Extends the job-level 'permissions' block to include 'issues: write' and 'pull-requests: write'. This allows '@semantic-release/github' to comment on released issues/PRs during the post-release success hook, preventing a 403 and non-zero job exit.

.github/workflows/tests.yml

@qodo-for-filiphric

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1)   📘 Rule violations (0)   📎 Requirement gaps (0)   🧑 Team insights (0)   📜 Skill insights (0)
🐞 ⛨ Security (1)
Context used
✅ Compliance rules (platform): 3 rules
✅ Team profiles: shay-qodo, avi-gl
Review effort: 🔍 Standard

Grey Divider


Remediation recommended

1. Job-wide elevated token scope 🐞 ⛨ Security
Description
The workflow grants issues: write and pull-requests: write at the job level, so every step
(including third-party actions like Cypress) runs with a token that can write to Issues/PRs on every
push, expanding the blast radius beyond the semantic-release step. This can be avoided by
isolating semantic-release into a dedicated job/workflow that only runs on main with the elevated
permissions.
Code

.github/workflows/tests.yml[R7-10]

+      contents: write        # semantic-release pushes tags / GitHub release
+      id-token: write        # required for npm trusted publishing (OIDC)
+      issues: write          # semantic-release comments on released issues
+      pull-requests: write   # semantic-release comments on released PRs
Evidence
The workflow is triggered on every push (not gated to main), and the permissions: block is
defined at the cypress-run job level, which means the resulting GITHUB_TOKEN scopes apply to the
entire job rather than a single step. Because that same job executes multiple steps including
third-party actions (Cypress and the semantic-release action), all of those steps inherit the added
issues: write and pull-requests: write permissions, increasing impact if any earlier step or
dependency is compromised or misused.

.github/workflows/tests.yml[1-10]
.github/workflows/tests.yml[20-35]
.github/workflows/tests.yml[2-10]
.github/workflows/tests.yml[11-36]

Teammate info & reasoning
Rollout/migration safety (default-off, fail-safe to legacy, no-event-loss)
Reason for choosing avi-gl: Extensive experience reviewing infrastructure/automation changes; well-suited to validate GitHub Actions token scopes for semantic-release GitHub commenting and overall pipeline security.
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 currently grants elevated `GITHUB_TOKEN` permissions (`issues: write`, `pull-requests: write` (and related write scopes like `contents: write`)) at the **job** level, which makes those permissions available to *every* step in the `cypress-run` job on every `push`. Only semantic-release needs these write permissions; test execution (checkout/npm/Cypress) typically only needs read access, so the current setup unnecessarily increases blast radius.

## Issue Context
GitHub Actions permissions are scoped at the workflow/job level (not step level), so adding write scopes for semantic-release also elevates the token used by all other steps and any third-party actions run in the same job. This workflow includes both test execution and a semantic-release step, and the workflow is triggered on `push` without restricting execution to `main`.

## Fix Focus Areas
- .github/workflows/tests.yml[1-36]
- .github/workflows/tests.yml[2-10]
- .github/workflows/tests.yml[11-36]

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


Grey Divider

Qodo Logo

@qodo-for-filiphric

Copy link
Copy Markdown

Qodo Fixer

No findings are within the configured fix scope. To change which findings are fixed, adjust the setting on your Qodo configuration page.

@cypress

cypress Bot commented Jun 28, 2026

Copy link
Copy Markdown

cypress-plugin-api    Run #209

Run Properties:  status check passed Passed #209  •  git commit 3a990c1fc5: ci: grant issues/PR write to fix semantic-release success step
Project cypress-plugin-api
Branch Review ci/fix-semantic-release-permissions
Run status status check passed Passed #209
Run duration 01m 20s
Commit git commit 3a990c1fc5: ci: grant issues/PR write to fix semantic-release success step
Committer Filip Hric
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 91
View all changes introduced in this branch ↗︎

@filiphric filiphric merged commit 45cd59d into main Jun 28, 2026
2 checks 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.

1 participant