Skip to content

Harden manual store submission workflow - #990

Open
PeterDaveHello wants to merge 11 commits into
masterfrom
codex/fix-manual-release-workflow-vulnerability
Open

Harden manual store submission workflow#990
PeterDaveHello wants to merge 11 commits into
masterfrom
codex/fix-manual-release-workflow-vulnerability

Conversation

@PeterDaveHello

@PeterDaveHello PeterDaveHello commented Jun 30, 2026

Copy link
Copy Markdown
Member

Motivation

Manual dispatches should validate release artifacts without exposing store credentials or entering the authenticated store submission path.

Description

  • Split .github/workflows/tagged-release.yml into a read-only manual_preflight job for workflow_dispatch and a push-only release job for v* tags.
  • Keep manual preflight runs free of store secrets, persisted checkout credentials, and workflow-level GH_TOKEN exposure.
  • Added release:submit:preflight and --preflight-only so manual runs validate required release artifacts and Firefox manifest metadata without invoking publish-extension.
  • Kept real Chrome, Firefox, and Edge store submission on the tag-push release path, where the real secrets.* values are injected.

Testing

  • git diff --check github/master...HEAD
  • workflow YAML parse check
  • node --import ./tests/setup/browser-shim.mjs --test tests/unit/release/submit-stores.test.mjs
  • npm run lint
  • npm test
  • npm run build
  • npm run release:firefox-sources
  • npm run release:submit:preflight without store secrets
  • GitHub Actions tests passed on this PR
  • CodeRabbit completed with no actionable comments

Codex Task

Summary by CodeRabbit

Summary

  • New Features

    • Added preflight checks to validate store-submission readiness without publishing.
    • Added an npm command for running store-submission checks independently.
    • Improved automated releases with artifact rebuilding, upload handling, and published-release detection.
  • Bug Fixes

    • Improved release validation, version synchronization, and retry handling.
    • Strengthened manifest version validation and submission reliability.
  • Tests

    • Expanded coverage for preflight, dry-run, submission, and failure scenarios.
  • Chores

    • Refined release permissions and authentication handling.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Note

Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported.

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f8b1a59b-53e1-44a1-9a10-109ddf815207

📥 Commits

Reviewing files that changed from the base of the PR and between e2421cd and 7aa8885.

📒 Files selected for processing (3)
  • .github/workflows/tagged-release.yml
  • scripts/submit-stores.mjs
  • tests/unit/release/submit-stores.test.mjs

Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

This PR separates manual preflight and tag-based release jobs, adds a preflight-only store submission command, refactors store submission for injected dependencies and environment handling, and expands unit-test coverage for validation and execution modes.

Changes

Tagged release flow split

Layer / File(s) Summary
Workflow split and release synchronization
.github/workflows/tagged-release.yml, package.json
The workflow uses separate manual preflight and tag-based release jobs. It synchronizes manifests with retries, reuses or creates releases, replaces uploaded artifacts, gates published releases, and exposes the preflight command.
Preflight flag and publish environment injection
scripts/submit-stores.mjs
parseArgs recognizes --preflight-only. Environment validation rejects blank and non-string values. runPublishExtension resolves the CLI and passes merged string environment values to the child process.
Store submission control flow and validation
scripts/submit-stores.mjs, tests/unit/release/submit-stores.test.mjs
submitStores gains dependency injection, manifest validation, explicit mode handling, preflight-only behavior, and conditional Firefox metadata updates. Tests cover publishing failures, validation ordering, dry-run behavior, environment fallback, successful submission, and deterministic JWT retries.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to 7aa88

The workflow now separates manual artifact validation from authenticated store submission, with store credentials limited to tag releases; no actionable merge-blocking risk remains after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant GitHubActions
  participant npm
  participant submitStores
  participant GitHubCLI

  GitHubActions->>npm: Manual dispatch runs release:submit:preflight
  npm->>submitStores: Invoke --preflight-only
  GitHubActions->>GitHubCLI: Tag release creates or reuses a release
  GitHubActions->>GitHubCLI: Upload artifacts with replacement enabled
  GitHubActions->>npm: Tag release runs store submission
  npm->>submitStores: Invoke store submission
Loading

Suggested reviewers: josstorer

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary change: strengthening the manual store submission workflow and its validation behavior.
Docstring Coverage ✅ Passed Docstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-manual-release-workflow-vulnerability

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.

@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Harden tagged-release workflow to prevent secret exposure on manual dispatch

🐞 Bug fix ⚙️ Configuration changes 🕐 10-20 Minutes

Grey Divider

AI Description

• Scope GH_TOKEN only to gh release steps executed on push-tag runs.
• Prevent workflow_dispatch checkouts from inheriting repository credentials.
• Split store submission into manual dry-run (dummy env only) vs push-only real submission
 (secrets).
Diagram

graph TD
A(("Workflow trigger")) --> B{{"Event type?"}}
B -->|"push v* tag"| C["Checkout (persist creds on push)"] --> D["Release steps (GH_TOKEN scoped)"] --> E["Submit stores (real secrets)"] --> F["Publish release (GH_TOKEN scoped)"]
B -->|"workflow_dispatch"| C --> G["Build + package"] --> H["Submit stores (dry-run, dummy env)"]
subgraph Legend
direction LR
_start(("Trigger")) ~~~ _decision{{"Decision"}} ~~~ _step["Step"]
end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Split into two workflows (release vs manual preflight)
  • ➕ Eliminates complex conditional logic in a single YAML
  • ➕ Makes secret-free manual workflow intent explicit
  • ➖ Some duplication of build/release steps across workflows
  • ➖ Requires keeping two workflows in sync
2. Force workflow_dispatch to run only from default branch ref
  • ➕ Further reduces attack surface by never executing untrusted refs for manual runs
  • ➕ Simplifies credential hardening requirements
  • ➖ Loses ability to validate release pipeline against branch-specific changes
3. Use GitHub Environments with required reviewers for store submission
  • ➕ Adds an approval gate even if a step is misconfigured in the future
  • ➕ Environment-scoped secrets limit accidental exposure
  • ➖ Operational overhead and slower releases
  • ➖ Requires additional repository configuration

Recommendation: The PR’s approach is a good minimal-scope hardening: it removes global token exposure, disables persisted checkout credentials for manual runs, and ensures manual store submission cannot access real secrets. Consider adding an Environment approval gate for the push-only store submission as a defense-in-depth follow-up.

Files changed (1) +33 / -13

Other (1) +33 / -13
tagged-release.ymlScope tokens and split store submission into push-only vs manual dry-run +33/-13

Scope tokens and split store submission into push-only vs manual dry-run

• Removes the global GH_TOKEN and injects it only on gh release steps that run on push-tag events. Updates checkout to avoid persisting repository credentials on workflow_dispatch. Splits store submission into a manual-only dry-run step using dummy env vars and a push-only real submission step using secrets.

.github/workflows/tagged-release.yml

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a3d0e2303d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/tagged-release.yml Outdated

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 hardens the tagged-release GitHub Actions workflow to prevent credential exposure when collaborators manually trigger workflow_dispatch, while keeping real store submissions restricted to trusted tag-push runs.

Changes:

  • Removed the workflow-wide GH_TOKEN and instead injects GH_TOKEN only into the push-only gh release steps.
  • Prevents credential persistence during manual runs by setting actions/checkout persist-credentials to only persist on push.
  • Splits store submission into a manual-only dry-run step (with dummy store env vars and forced --dry-run) and a push-only real submission step (with secrets.*).

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

@qodo-code-review

qodo-code-review Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Completed rerun skips asset validation ✗ Dismissed 🐞 Bug ☼ Reliability
Description
When all three completion markers exist, this condition bypasses the required-asset validation loop,
after which SKIP_STORE_SUBMISSION=true suppresses rebuilding/uploading and the draft is still
published. A draft whose assets were deleted or never fully uploaded can therefore be published
without one or more release binaries.
Code

.github/workflows/tagged-release.yml[R263-265]

+                if ! [ "$skip_chrome_store" = "true" ] \
+                  || ! [ "$skip_firefox_store" = "true" ] \
+                  || ! [ "$skip_edge_store" = "true" ]; then
Evidence
The validation loop is entered only when at least one store is not complete, while the all-complete
branch sets SKIP_STORE_SUBMISSION; artifact build/upload steps are then skipped, but release
publication remains enabled.

.github/workflows/tagged-release.yml[260-285]
.github/workflows/tagged-release.yml[347-362]
.github/workflows/tagged-release.yml[462-464]

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

## Issue description
An all-stores-complete rerun bypasses release-asset validation and can publish an incomplete draft.

## Issue Context
The current asset loop runs only for a partial store completion state. When every store marker exists, later conditions skip artifact generation/upload but still publish the release.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[260-285]
- .github/workflows/tagged-release.yml[347-362]
- .github/workflows/tagged-release.yml[462-464]

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


2. Release job never builds extension artifacts ✗ Dismissed 🐞 Bug ≡ Correctness
Description
The tag-push release job runs npm ci and later npm run build:safari and `npm run
release:firefox-sources, but never runs the main npm run build` step that produces
build/chromium.zip and build/firefox.zip. Since npm run release:firefox-sources only creates
the Firefox sources archive (not the extension zips) and npm run build:safari depends on `npm run
build internally but is gated behind SKIP_STORE_SUBMISSION != 'true' && REUSE_RELEASE_ARTIFACTS !=
'true'`, when those flags are set the extension zips never get created, causing subsequent artifact
upload and store submission preflight checks in scripts/submit-stores.mjs to fail.
Code

.github/workflows/tagged-release.yml[R346-350]

+      - run: npm run build:safari
+        if: env.SKIP_RELEASE != 'true' && env.SKIP_STORE_SUBMISSION != 'true' && env.REUSE_RELEASE_ARTIFACTS != 'true'
+
+      - run: npm run release:firefox-sources
+        if: env.SKIP_RELEASE != 'true' && env.SKIP_FIREFOX_STORE != 'true'
Evidence
The release job's steps only call npm ci (line 301-302), then conditionally npm run build:safari
(line 346) and npm run release:firefox-sources (line 349), but there is no unconditional `npm run
build` step producing build/chromium.zip and build/firefox.zip used later at lines 352-357 for
upload and required by scripts/submit-stores.mjs STORE_ARTIFACTS (chrome: build/chromium.zip,
firefox: build/firefox.zip, firefox-sources.zip). safari/build.sh line 5 runs 'npm run build'
internally but that step (npm run build:safari) is skipped when SKIP_STORE_SUBMISSION or
REUSE_RELEASE_ARTIFACTS is true, meaning on a normal fresh tag push where none of these skip flags
are set, build:safari does trigger the underlying build via its own script — but if
REUSE_RELEASE_ARTIFACTS is true (partial rerun) the build step gets skipped entirely, yet
build/chromium.zip and build/firefox.zip are restored via 'Restore release artifacts for partial
rerun' step, which is fine. However, if SKIP_STORE_SUBMISSION is true (all stores done) but the
release still needs to publish, the workflow depends on already-uploaded artifacts, which is fine
too. The core issue is that the primary build artifacts (build/chromium.zip, build/firefox.zip)
are only produced as a side effect of npm run build:safari invoking safari/build.sh which
internally calls npm run build (confirmed in safari/build.sh line 5). This creates an implicit,
fragile coupling: if npm run build:safari's step condition ever evaluates false while
chrome/firefox store submission is still required (e.g., a state combination not fully covered), the
required zips are missing.

safari/build.sh[3-5]
.github/workflows/tagged-release.yml[346-361]
scripts/submit-stores.mjs[35-38]

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 tag-push `release` job in `.github/workflows/tagged-release.yml` relies on `npm run build:safari` (which internally shells out to `npm run build`) as the only source of the Chromium/Firefox build outputs (`build/chromium.zip`, `build/firefox.zip`), and that step is conditionally skipped (`if: env.SKIP_RELEASE != 'true' && env.SKIP_STORE_SUBMISSION != 'true' && env.REUSE_RELEASE_ARTIFACTS != 'true'`). This creates an implicit and fragile coupling between the Safari build script and the generation of the core web-extension artifacts, risking missing `build/chromium.zip`/`build/firefox.zip` if the condition logic changes or if a future maintainer decouples Safari build.

## Issue Context
- `safari/build.sh` line 5 calls `npm run build` as a side effect before invoking `xcrun`.
- The release job's artifact upload step (lines 352-357) and the store submission scripts (`scripts/submit-stores.mjs` lines 35-38) require `build/chromium.zip` and `build/firefox.zip` to already exist.
- There's no explicit, unconditional `npm run build` step in the release job.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[346-350]

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


3. Uncaught remote version read failure ✓ Resolved 🐞 Bug ☼ Reliability
Description
In the version-sync loop, a failure to extract remote_version from FETCH_HEAD:src/manifest.json
falls through to the rebase/push path, because the script only special-cases
release_version_requires_skip exit code 2 and does not handle a failing git show | node
pipeline. This can incorrectly rebase/push master even though the workflow could not verify whether
the remote already contains an equivalent/newer version.
Code

.github/workflows/tagged-release.yml[R155-160]

+                remote_version="$(
+                  git show FETCH_HEAD:src/manifest.json \
+                    | node -p "JSON.parse(require('fs').readFileSync(0, 'utf8')).version"
+                )"
+                release_version_requires_skip "$remote_version" "$VERSION"
+              then
Evidence
The loop assigns remote_version using git show FETCH_HEAD:src/manifest.json | node -p ... and
then calls release_version_requires_skip. Only release_version_requires_skip's exit(2) is
handled explicitly; any earlier failure in the assignment/pipeline causes the elif to be false and
the script proceeds to the subsequent git rebase FETCH_HEAD / git push branches, effectively
attempting to sync even though it could not read the remote version.

.github/workflows/tagged-release.yml[145-172]

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 release-version sync loop computes `remote_version` via `git show ... | node -p ...` inside an `elif` condition. If that command substitution fails (missing file in `FETCH_HEAD`, JSON parse error, etc.), the condition is treated as false and the script proceeds to `git rebase` / `git push` without knowing the remote manifest version.

### Issue Context
This is in the `Push files` step, inside the `for attempt in ...` retry loop.

### Fix Focus Areas
- .github/workflows/tagged-release.yml[145-171]

### Suggested fix
1) Split the `remote_version` extraction from the `elif` condition, and explicitly handle failures by warning + skipping version sync for this run (or retrying separately):

```bash
remote_version="$({ git show FETCH_HEAD:src/manifest.json | node -p '...'; } )" \
 || { report_sync_warning "Failed to read origin/master manifest version; skipping the release version sync"; break; }

if release_version_requires_skip "$remote_version" "$VERSION"; then
 ...
elif [ "$?" -eq 2 ]; then
 ...
fi
```

2) Alternatively, keep it inside the condition but add an explicit `else`/branch that detects the extraction failure (non-zero exit from the assignment command) and breaks with a warning, rather than falling through to `git rebase`.

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


View high (4)
4. Invalid concurrency queue key ✗ Dismissed 🐞 Bug ≡ Correctness
Description
The release job adds queue: max, but GitHub Actions job concurrency accepts only group and
cancel-in-progress. The workflow is rejected during validation, so tag-triggered releases cannot
run.
Code

.github/workflows/tagged-release.yml[48]

+      queue: max
Evidence
The changed release job defines its concurrency mapping with group, the unsupported queue key,
and cancel-in-progress; this job is the push-only path responsible for all release and
store-submission steps.

.github/workflows/tagged-release.yml[43-49]
.github/workflows/tagged-release.yml[339-409]

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 release job uses the unsupported `queue` property under GitHub Actions `concurrency`. This prevents the workflow from validating and blocks tag-triggered releases.

## Issue Context
GitHub Actions job-level concurrency supports `group` and `cancel-in-progress`; it does not support `queue`. Keeping `cancel-in-progress: false` allows the active release run to finish, but GitHub Actions does not provide a `queue: max` setting.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[46-49]

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


5. Shallow rebase can fail ✓ Resolved 🐞 Bug ☼ Reliability
Description
The release workflow rebases the version-bump commit onto origin/master ("git rebase FETCH_HEAD")
without ensuring the checkout has enough git history, which can fail in CI and abort the release
after a tag push. This can intermittently break releases when the merge-base/history required for
rebase isn’t available locally.
Code

.github/workflows/tagged-release.yml[R84-87]

+            git commit -m "release v${VERSION}"
+            git fetch origin master
+            git rebase FETCH_HEAD
+            git push origin HEAD:master
Evidence
The workflow now performs a rebase during the version-bump push sequence, but the checkout step does
not configure history depth and the fetch step doesn’t request additional history, making `git
rebase` prone to failing due to missing ancestry/merge-base data in CI clones.

.github/workflows/tagged-release.yml[50-54]
.github/workflows/tagged-release.yml[76-88]

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 `release` job creates a commit and then runs `git fetch origin master` + `git rebase FETCH_HEAD`. If the runner’s checkout/fetch does not include the required ancestry, `git rebase` can fail and stop the workflow.

### Issue Context
This logic was introduced in the updated `Push files` step. The job’s checkout step does not specify any history depth, and the subsequent `git fetch origin master` doesn’t explicitly deepen/unshallow the clone.

### Fix Focus Areas
- .github/workflows/tagged-release.yml[50-88]

### Suggested fix
Pick one:
1. Ensure a full (or sufficiently deep) history before rebasing:
  - Add `fetch-depth: 0` to the `actions/checkout` step that checks out `master`, **or**
  - Add an explicit `git fetch --unshallow origin master` (or `git fetch --depth=<N> origin master`) before `git rebase`.

2. Avoid rebasing in CI:
  - Replace the rebase with a plain push and let the push fail if `master` moved, or use a safer strategy (e.g., `git pull --rebase` with full history available).

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


6. Release ignores push failures ✗ Dismissed 🐞 Bug ☼ Reliability
Description
The workflow marks the Push files step as continue-on-error: true, but later steps still
create/edit the GitHub Release, upload artifacts, and submit to stores. If the commit/push fails
(e.g., branch protection), the workflow can publish artifacts built from unpushed local changes,
diverging from any commit in the repo.
Code

.github/workflows/tagged-release.yml[R77-83]

      - name: Push files
-        if: github.event_name == 'push'
        continue-on-error: true
        run: |
          git config --global user.email "github-actions[bot]@users.noreply.github.com"
          git config --global user.name "github-actions[bot]"
-          git commit -am "release v${{ env.VERSION }}"
+          git commit -am "release v${VERSION}"
          git push
Evidence
The workflow explicitly allows the commit/push step to fail without stopping, but still runs release
creation/upload/store submission steps afterward, enabling publication from a state that might not
exist in the repository.

.github/workflows/tagged-release.yml[77-84]
.github/workflows/tagged-release.yml[85-112]
.github/workflows/tagged-release.yml[113-136]

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 release workflow can proceed to create/upload/publish a GitHub Release and submit to stores even when the `git commit`/`git push` step fails, producing a release that doesn’t correspond to a committed repository state.

### Issue Context
- `continue-on-error: true` suppresses failures in the commit/push step.
- Subsequent steps publish external artifacts regardless.

### Fix Focus Areas
- .github/workflows/tagged-release.yml[77-84]
- .github/workflows/tagged-release.yml[85-136]

### Suggested change
- Remove `continue-on-error: true`.
- If the intent is to tolerate "nothing to commit", explicitly handle that case while still failing on real push failures, e.g.:
 - Check `git diff --quiet` before committing.
 - Only run `git push` when a commit was created.
 - Keep `set -euo pipefail` so an actual push failure stops the workflow.
- Optionally gate later release/upload/store-submission steps on a successful push outcome.

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


7. Release builds wrong ref ✗ Dismissed 🐞 Bug ≡ Correctness
Description
The release job triggers on v* tag pushes but force-checks out master, so artifacts and store
submissions can be built from a different commit than the tag that the GitHub Release is created
for. This breaks release integrity/reproducibility when tags are created from non-master commits
or if master moves unexpectedly.
Code

.github/workflows/tagged-release.yml[R50-53]

      - uses: actions/checkout@v7
        with:
-          ref: ${{ github.event_name == 'push' && 'master' || github.ref_name }}
+          ref: master
+          persist-credentials: true
Evidence
The workflow is triggered by tag pushes, but the release job explicitly checks out master while
deriving the release tag/version from the pushed tag name, so the released artifacts can diverge
from the tag’s commit.

.github/workflows/tagged-release.yml[13-15]
.github/workflows/tagged-release.yml[49-53]
.github/workflows/tagged-release.yml[60-61]
.github/workflows/tagged-release.yml[85-90]

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 release workflow runs on tag pushes (`v*`) but checks out `master`, which can cause releases to publish artifacts that don’t match the tagged commit.

### Issue Context
- Workflow trigger is a tag push.
- Release tag/version are derived from `github.ref_name`.
- The repository contents used for the build are taken from `master`.

### Fix Focus Areas
- .github/workflows/tagged-release.yml[13-15]
- .github/workflows/tagged-release.yml[49-53]

### Suggested change
- In the `release` job, check out the tag ref/commit (e.g., `ref: ${{ github.ref }}` or `ref: ${{ github.ref_name }}`) so the build matches the tag.
- If you still need to commit version bumps back to `master`, do a separate explicit checkout/switch to `master` only for the commit/push step (after building or in a separate job).

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



Remediation recommended

8. Marker failure repeats submission ✗ Dismissed 🐞 Bug ☼ Reliability
Description
If a store submission succeeds but its completion-marker upload exhausts retries, this new exit 1
fails the job without recording completion. The next run only checks marker assets, so it invokes
the authenticated submission for that store again despite the prior successful external operation.
Code

.github/workflows/tagged-release.yml[R385-387]

+            if [ "$attempt" -eq 5 ]; then
+              echo "::error::Failed to upload the Chrome store completion marker after ${attempt} attempts"
+              exit 1
Evidence
Each store command runs before its marker step; marker retry exhaustion exits the workflow, and
rerun skip flags are derived solely from marker assets. submitStores delegates to the publishing
CLI and returns only after that external operation, so a marker failure occurs after submission
completion.

.github/workflows/tagged-release.yml[239-258]
.github/workflows/tagged-release.yml[364-390]
.github/workflows/tagged-release.yml[396-420]
.github/workflows/tagged-release.yml[434-456]
scripts/submit-stores.mjs[313-322]

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

## Issue description
A completion-marker persistence failure after successful store submission causes reruns to submit the same version again.

## Issue Context
The same ordering and failure mode exists for Chrome, Firefox, and Edge. Make reruns reconcile durable store state, or otherwise avoid failing into an unmarked ambiguous state after the external submission has completed.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[364-390]
- .github/workflows/tagged-release.yml[396-420]
- .github/workflows/tagged-release.yml[434-456]
- .github/workflows/tagged-release.yml[239-258]

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


9. Chrome error exceeds limit ✗ Dismissed 📘 Rule violation ⚙ Maintainability
Description
The Chrome completion-marker failure message is approximately 108 characters wide, exceeding the
100-character source-line limit. The message should be emitted from wrapped shell lines.
Code

.github/workflows/tagged-release.yml[386]

+              echo "::error::Failed to upload the Chrome store completion marker after ${attempt} attempts"
Evidence
Rule 2261946 limits non-comment source lines to 100 characters, while the changed Chrome marker
error at line 386 exceeds that limit.

Rule 2261946: Limit source line length to 100 characters
.github/workflows/tagged-release.yml[386-386]

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 Chrome completion-marker failure message exceeds the 100-character source-line limit.

## Issue Context
Preserve the emitted message while splitting the shell command into physical lines of at most 100 characters.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[386-386]

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


10. Chrome upload exceeds limit ✗ Dismissed 📘 Rule violation ⚙ Maintainability
Description
The Chrome completion-marker upload condition is approximately 111 characters wide, exceeding the
100-character source-line limit. Wrapping the command would keep the retry loop readable.
Code

.github/workflows/tagged-release.yml[382]

+            if gh release upload "$RELEASE_TAG" --clobber build/store-submission-complete.chrome.marker; then
Evidence
Rule 2261946 limits non-comment source lines to 100 characters, while the changed Chrome marker
upload at line 382 exceeds that limit.

Rule 2261946: Limit source line length to 100 characters
.github/workflows/tagged-release.yml[382-382]

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 Chrome completion-marker upload condition exceeds the 100-character source-line limit.

## Issue Context
Use a shell line continuation to keep each physical line at or below 100 characters.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[382-382]

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


View medium (23)
11. Edge error exceeds limit ✗ Dismissed 📘 Rule violation ⚙ Maintainability
Description
The Edge completion-marker failure message is approximately 106 characters wide, exceeding the
100-character source-line limit. The message should be emitted from wrapped shell lines.
Code

.github/workflows/tagged-release.yml[452]

+              echo "::error::Failed to upload the Edge store completion marker after ${attempt} attempts"
Evidence
Rule 2261946 limits non-comment source lines to 100 characters, while the changed Edge marker error
at line 452 exceeds that limit.

Rule 2261946: Limit source line length to 100 characters
.github/workflows/tagged-release.yml[452-452]

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 Edge completion-marker failure message exceeds the 100-character source-line limit.

## Issue Context
Preserve the emitted message while splitting the shell command into physical lines of at most 100 characters.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[452-452]

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


12. Firefox upload exceeds limit ✗ Dismissed 📘 Rule violation ⚙ Maintainability
Description
The Firefox completion-marker upload condition is approximately 112 characters wide, exceeding the
100-character source-line limit. Wrapping the command would keep the retry loop readable.
Code

.github/workflows/tagged-release.yml[412]

+            if gh release upload "$RELEASE_TAG" --clobber build/store-submission-complete.firefox.marker; then
Evidence
Rule 2261946 limits non-comment source lines to 100 characters, while the changed Firefox marker
upload at line 412 exceeds that limit.

Rule 2261946: Limit source line length to 100 characters
.github/workflows/tagged-release.yml[412-412]

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 Firefox completion-marker upload condition exceeds the 100-character source-line limit.

## Issue Context
Use a shell line continuation to keep each physical line at or below 100 characters.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[412-412]

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


13. Edge upload exceeds limit ✗ Dismissed 📘 Rule violation ⚙ Maintainability
Description
The Edge completion-marker upload condition is approximately 109 characters wide, exceeding the
100-character source-line limit. Wrapping the command would keep the retry loop readable.
Code

.github/workflows/tagged-release.yml[448]

+            if gh release upload "$RELEASE_TAG" --clobber build/store-submission-complete.edge.marker; then
Evidence
Rule 2261946 limits non-comment source lines to 100 characters, while the changed Edge marker upload
at line 448 exceeds that limit.

Rule 2261946: Limit source line length to 100 characters
.github/workflows/tagged-release.yml[448-448]

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 Edge completion-marker upload condition exceeds the 100-character source-line limit.

## Issue Context
Use a shell line continuation to keep each physical line at or below 100 characters.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[448-448]

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


14. Restore command exceeds limit ✗ Dismissed 📘 Rule violation ⚙ Maintainability
Description
The new restored_version assignment is approximately 126 characters wide, exceeding the
100-character source-line limit. Its inline Node expression should be wrapped for maintainability.
Code

.github/workflows/tagged-release.yml[337]

+            restored_version="$(node -p 'JSON.parse(require("fs").readFileSync(process.argv[1], "utf8")).version' "$manifest")"
Evidence
Rule 2261946 limits non-comment source lines to 100 characters, while the changed restored_version
assignment at line 337 is well over that limit.

Rule 2261946: Limit source line length to 100 characters
.github/workflows/tagged-release.yml[337-337]

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 command that reads the restored manifest version exceeds the 100-character source-line limit.

## Issue Context
Split the command substitution or Node expression across physical lines without changing its behavior.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[337-337]

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


15. Firefox error exceeds limit ✗ Dismissed 📘 Rule violation ⚙ Maintainability
Description
The Firefox completion-marker failure message is approximately 109 characters wide, exceeding the
100-character source-line limit. The message should be emitted from wrapped shell lines.
Code

.github/workflows/tagged-release.yml[416]

+              echo "::error::Failed to upload the Firefox store completion marker after ${attempt} attempts"
Evidence
Rule 2261946 limits non-comment source lines to 100 characters, while the changed Firefox marker
error at line 416 exceeds that limit.

Rule 2261946: Limit source line length to 100 characters
.github/workflows/tagged-release.yml[416-416]

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 Firefox completion-marker failure message exceeds the 100-character source-line limit.

## Issue Context
Preserve the emitted message while splitting the shell command into physical lines of at most 100 characters.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[416-416]

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


16. Manifest error exceeds limit ✗ Dismissed 📘 Rule violation ⚙ Maintainability
Description
The new invalid-manifest error command is 113 characters wide, exceeding the 100-character
source-line limit. This makes the release workflow harder to scan and maintain.
Code

.github/workflows/tagged-release.yml[172]

+                echo "::error::Cannot verify release version state; origin/master has an invalid manifest version"
Evidence
Rule 2261946 limits non-comment source lines to 100 characters, while the changed command at line
172 is 113 characters wide.

Rule 2261946: Limit source line length to 100 characters
.github/workflows/tagged-release.yml[172-172]

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 invalid remote-manifest error command exceeds the 100-character source-line limit.

## Issue Context
Preserve the error text while splitting the shell command into physical lines of at most 100 characters.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[172-172]

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


17. Commit error exceeds limit ✗ Dismissed 📘 Rule violation ⚙ Maintainability
Description
The new release-sync error command is 105 characters wide, exceeding the 100-character source-line
limit. This reduces readability in the embedded workflow script.
Code

.github/workflows/tagged-release.yml[143]

+            echo "::error::Failed to commit the release version sync; cannot verify release version state"
Evidence
Rule 2261946 limits non-comment source lines to 100 characters, while the changed command at line
143 is 105 characters wide.

Rule 2261946: Limit source line length to 100 characters
.github/workflows/tagged-release.yml[143-143]

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 release-sync commit error command exceeds the 100-character source-line limit.

## Issue Context
Preserve the emitted error message while splitting the shell command into physical lines of at most 100 characters.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[143-143]

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


18. Upload condition overlong ✗ Dismissed 📘 Rule violation ⚙ Maintainability
Description
The new release-upload step condition is 159 characters wide, substantially exceeding the
100-character source-line limit. Its three predicates should be wrapped to keep the workflow
readable.
Code

.github/workflows/tagged-release.yml[361]

+        if: env.SKIP_RELEASE != 'true' && env.SKIP_STORE_SUBMISSION != 'true' && env.REUSE_RELEASE_ARTIFACTS != 'true'
Evidence
The changed upload condition is 159 characters wide, violating PR Compliance ID 2261946's
100-character maximum.

Rule 2261946: Limit source line length to 100 characters
.github/workflows/tagged-release.yml[361-361]

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 release artifact upload condition exceeds the 100-character source-line limit.

## Issue Context
Retain all three existing predicates while formatting the GitHub Actions condition across multiple physical lines.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[361-361]

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


19. Push warning overlong ✗ Dismissed 📘 Rule violation ⚙ Maintainability
Description
The newly added failed-push warning is 107 characters wide, exceeding the 100-character source-line
limit. Wrapping it would keep the workflow consistent with the required formatting policy.
Code

.github/workflows/tagged-release.yml[181]

+                report_sync_warning "Failed to push the release version sync; continuing with the release"
Evidence
The checklist's 100-character maximum applies to this changed workflow source line, which is 107
characters wide.

Rule 2261946: Limit source line length to 100 characters
.github/workflows/tagged-release.yml[181-181]

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 failed release-version push warning exceeds the 100-character limit.

## Issue Context
Preserve the warning and release behavior while splitting the invocation into shorter physical lines.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[181-181]

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


20. Sync skip warning overlong ✗ Dismissed 📘 Rule violation ⚙ Maintainability
Description
The newly added report_sync_warning invocation is 141 characters wide, exceeding the 100-character
source-line limit. This makes the release workflow harder to scan and maintain.
Code

.github/workflows/tagged-release.yml[167]

+                report_sync_warning "Skipping release version sync; origin/master already has an equivalent or newer version than v${VERSION}"
Evidence
PR Compliance ID 2261946 limits non-comment source lines to 100 characters; the focused workflow
line is 141 characters wide.

Rule 2261946: Limit source line length to 100 characters
.github/workflows/tagged-release.yml[167-167]

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 release-version sync warning line exceeds the 100-character limit.

## Issue Context
Preserve the warning text and behavior while splitting the shell command across physical lines.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[167-167]

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


21. Rebase warning overlong ✗ Dismissed 📘 Rule violation ⚙ Maintainability
Description
The newly added rebase-conflict warning is 113 characters wide, exceeding the 100-character
source-line limit. This reduces readability in an already complex release script.
Code

.github/workflows/tagged-release.yml[175]

+                report_sync_warning "Release version sync conflicted with origin/master; skipping the master push"
Evidence
PR Compliance ID 2261946 requires physical source lines at or below 100 characters; this changed
line is 113 characters wide.

Rule 2261946: Limit source line length to 100 characters
.github/workflows/tagged-release.yml[175-175]

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 rebase-conflict warning line exceeds the 100-character limit.

## Issue Context
Keep the same warning semantics while wrapping the shell invocation onto shorter physical lines.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[175-175]

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


22. Safari build condition overlong ✗ Dismissed 📘 Rule violation ⚙ Maintainability
Description
The new build:safari step condition is 112 characters wide, exceeding the 100-character
source-line limit. The compound expression should be formatted across shorter YAML lines.
Code

.github/workflows/tagged-release.yml[347]

+        if: env.SKIP_RELEASE != 'true' && env.SKIP_STORE_SUBMISSION != 'true' && env.REUSE_RELEASE_ARTIFACTS != 'true'
Evidence
PR Compliance ID 2261946 requires every non-comment source line to be no wider than 100 characters;
this changed condition is 112 characters wide.

Rule 2261946: Limit source line length to 100 characters
.github/workflows/tagged-release.yml[347-347]

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 `build:safari` step condition exceeds the 100-character source-line limit.

## Issue Context
Use an equivalent multiline GitHub Actions expression or YAML scalar without changing the condition's logic.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[347-347]

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


23. Firefox metadata step ignores skip-firefox flag ✗ Dismissed 🐞 Bug ≡ Correctness
Description
The Update Firefox metadata step runs whenever env.SKIP_RELEASE != 'true', without checking
env.SKIP_FIREFOX_STORE, so on a partial-release rerun where Firefox submission was already marked
complete (SKIP_FIREFOX_STORE=true), this step still executes `npm run
release:update-firefox-metadata` and attempts to PATCH the already-submitted Firefox version's
release notes using the current manifest version, potentially failing or mutating already-finalized
AMO metadata unnecessarily.
Code

.github/workflows/tagged-release.yml[R425-431]

+      - name: Update Firefox metadata
+        run: npm run release:update-firefox-metadata -- --version "$VERSION"
+        if: env.SKIP_RELEASE != 'true'
+        env:
+          FIREFOX_EXTENSION_ID: ${{ secrets.FIREFOX_EXTENSION_ID }}
+          FIREFOX_JWT_ISSUER: ${{ secrets.FIREFOX_JWT_ISSUER }}
+          FIREFOX_JWT_SECRET: ${{ secrets.FIREFOX_JWT_SECRET }}
Evidence
Lines 250-258 set SKIP_FIREFOX_STORE=true when the Firefox marker asset already exists on the
release, meaning the Firefox store submission step at line 395-398 is skipped via `if:
env.SKIP_RELEASE != 'true' && env.SKIP_FIREFOX_STORE != 'true'`. But the 'Update Firefox metadata'
step at line 425-431 only checks if: env.SKIP_RELEASE != 'true', missing the
env.SKIP_FIREFOX_STORE != 'true' guard present on the sibling Submit/Mark Firefox steps, so it
still runs and calls the AMO PATCH endpoint even when Firefox submission was already completed in a
prior run.

.github/workflows/tagged-release.yml[395-403]
.github/workflows/tagged-release.yml[425-431]

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 'Update Firefox metadata' step in the release job runs unconditionally whenever `env.SKIP_RELEASE != 'true'`, but it should also be skipped when `env.SKIP_FIREFOX_STORE == 'true'` (i.e., Firefox submission was already completed in a prior partial run), matching the guard used by the 'Submit Firefox store' and 'Mark Firefox store submission complete' steps.

## Issue Context
- Lines 238-258 compute `SKIP_FIREFOX_STORE` based on whether a Firefox completion marker asset already exists on the GitHub release.
- The 'Submit Firefox store' step (lines 395-398) and 'Mark Firefox store submission complete' step (lines 405-407) both check `env.SKIP_FIREFOX_STORE != 'true'`.
- The 'Update Firefox metadata' step (lines 425-431) omits this check, so it re-runs the AMO metadata PATCH even when Firefox submission was already marked complete.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[425-431]

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


24. Overlong git show command ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
A newly added workflow command line exceeds the 100-character maximum, reducing readability and
violating the repository line-length policy. This can make future maintenance and review of the
release workflow harder.
Code

.github/workflows/tagged-release.yml[R154-155]

+                "$(git show FETCH_HEAD:src/manifest.json | node -p "JSON.parse(require('fs').readFileSync(0, 'utf8')).version")" \
+                "$VERSION"; then
Evidence
PR Compliance ID 2261946 requires non-comment source lines to be ≤100 characters. The workflow line
containing the $(git show ... | node -p ...) substitution is a single physical line well over that
limit.

Rule 2261946: Limit source line length to 100 characters
.github/workflows/tagged-release.yml[153-156]

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

## Issue description
A line in the release workflow exceeds the 100-character maximum line length requirement.

## Issue Context
The repository enforces a 100-character max line length for source files. The `git show ... | node -p ...` command is currently written on a single very long physical line.

## Fix Focus Areas
- .github/workflows/tagged-release.yml[153-156]

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


25. Overlong manifest version test ✗ Dismissed 📘 Rule violation ⚙ Maintainability
Description
A newly added test line defining the invalid version list exceeds the 100-character limit. This
violates the repo line-length policy and makes the test harder to read.
Code

tests/unit/release/submit-stores.test.mjs[R171-172]

+  for (const version of ['next', '2.6', '01.2.3', '70000.1.1', ' 2.6.1 ', '0.0.0', '0.0.0.0']) {
+    assert.equal(isValidManifestVersion(version), false)
Evidence
PR Compliance ID 2261946 requires non-comment source lines to be <= 100 characters. The added `for
(const version of [...] )` line contains a long inline array literal that exceeds this limit.

Rule 2261946: Limit source line length to 100 characters
tests/unit/release/submit-stores.test.mjs[171-172]

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

## Issue description
A newly added test line exceeds the 100-character max line length.

## Issue Context
The test enumerates invalid manifest versions in a single array literal on one line.

## Fix Focus Areas
- tests/unit/release/submit-stores.test.mjs[171-172]

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


26. Overlong release tag error line ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
The echo "::error::..." line in the workflow exceeds the 100-character limit. This reduces
readability and violates the repository line-length policy.
Code

.github/workflows/tagged-release.yml[79]

+            echo "::error::Release tags must use canonical 3-4 part versions with components from 0 to 65535 and at least one non-zero component"

[Comment truncated to fit github's 65,536-char limit.]

@PeterDaveHello
PeterDaveHello force-pushed the codex/fix-manual-release-workflow-vulnerability branch from a3d0e23 to c8380f7 Compare July 3, 2026 15:51

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

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

Comment thread scripts/submit-stores.mjs
Comment thread .github/workflows/tagged-release.yml

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a preflight-only mode to the store submission script and exposes it via a new npm script. It refactors the submission logic to support dependency injection, enabling comprehensive unit testing of different submission modes and failure paths. The review feedback suggests adding a defensive null check for the parsed manifest object to prevent a potential TypeError when accessing its version property.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread scripts/submit-stores.mjs Outdated
Comment thread .github/workflows/tagged-release.yml
Comment thread .github/workflows/tagged-release.yml Outdated
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit c8380f7

@kilo-code-bot

kilo-code-bot Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (4 files)
  • .github/workflows/tagged-release.yml - split manual_preflight and release jobs, hardened credential boundaries
  • package.json - added release:submit:preflight script
  • scripts/submit-stores.mjs - refactored with dependency injection, added preflight mode, nullish env filtering, manifest validation
  • tests/unit/release/submit-stores.test.mjs - expanded coverage for preflight, env handling, and platform-specific spawn behavior
Previous Review Summaries (11 snapshots, latest commit a122e5c)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit a122e5c)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (4 files)
  • .github/workflows/tagged-release.yml - split manual_preflight and release jobs, hardened credential boundaries
  • package.json - added release:submit:preflight script
  • scripts/submit-stores.mjs - refactored with dependency injection, added preflight mode, nullish env filtering, manifest validation
  • tests/unit/release/submit-stores.test.mjs - expanded coverage for preflight, env handling, and platform-specific spawn behavior

Previous review (commit 18d1963)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (4 files)
  • .github/workflows/tagged-release.yml - split manual_preflight and release jobs, hardened credential boundaries
  • package.json - added release:submit:preflight script
  • scripts/submit-stores.mjs - refactored with dependency injection, added preflight mode, nullish env filtering, manifest validation
  • tests/unit/release/submit-stores.test.mjs - expanded coverage for preflight, env handling, and platform-specific spawn behavior

Previous review (commit 3e842ff)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (4 files)
  • .github/workflows/tagged-release.yml - pre-existing release-source and push-failure behavior kept as-is
  • package.json - added release:submit:preflight script
  • scripts/submit-stores.mjs - added preflight mode, env merging, nullish filtering, manifest validation
  • tests/unit/release/submit-stores.test.mjs - added preflight and env-handling coverage

Previous review (commit 3d3e9f0)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (4 files)
  • .github/workflows/tagged-release.yml
  • package.json
  • scripts/submit-stores.mjs
  • tests/unit/release/submit-stores.test.mjs

Previous review (commit 875c42f)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (4 files)
  • .github/workflows/tagged-release.yml
  • package.json
  • scripts/submit-stores.mjs
  • tests/unit/release/submit-stores.test.mjs

Previous review (commit 5f4ad50)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (4 files)
  • .github/workflows/tagged-release.yml
  • scripts/submit-stores.mjs
  • package.json
  • tests/unit/release/submit-stores.test.mjs

Previous review (commit 20f69a1)

Status: 2 Issues Found (Previously Flagged) | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
.github/workflows/tagged-release.yml 52 Release job checks out master instead of the tag ref, so artifacts may not match the tagged commit
.github/workflows/tagged-release.yml 78 continue-on-error: true on "Push files" step allows workflow to proceed with release/upload/store-submission even if git push fails
Files Reviewed (4 files)
  • .github/workflows/tagged-release.yml - 2 issues (previously flagged by qodo-code-review[bot]; still present on lines 52 and 78)
  • scripts/submit-stores.mjs - No issues
  • package.json - No issues
  • tests/unit/release/submit-stores.test.mjs - No issues

Fix these issues in Kilo Cloud

Previous review (commit 2302190)

Status: 2 Issues Found (Previously Flagged) | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
.github/workflows/tagged-release.yml 52 Release job checks out master instead of the tag ref, so artifacts may not match the tagged commit
.github/workflows/tagged-release.yml 78 continue-on-error: true on "Push files" step allows workflow to proceed with release/upload/store-submission even if git push fails
Files Reviewed (4 files)
  • .github/workflows/tagged-release.yml - 2 issues (previously flagged by qodo-code-review[bot]; still present on lines 52 and 78)
  • scripts/submit-stores.mjs - No issues
  • package.json - No issues
  • tests/unit/release/submit-stores.test.mjs - No issues

Previous review (commit a87ab63)

Status: 2 Issues Found (Previously Flagged) | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
.github/workflows/tagged-release.yml 52 Release job checks out master instead of the tag ref, so artifacts may not match the tagged commit
.github/workflows/tagged-release.yml 78 continue-on-error: true on "Push files" step allows workflow to proceed with release/upload/store-submission even if git push fails
Files Reviewed (4 files)
  • .github/workflows/tagged-release.yml - 2 issues (previously flagged by qodo-code-review[bot]; still present on lines 52 and 78)
  • scripts/submit-stores.mjs - No issues
  • package.json - No issues
  • tests/unit/release/submit-stores.test.mjs - No issues

Previous review (commit e08da38)

Status: 2 Issues Found (Previously Flagged) | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
.github/workflows/tagged-release.yml 52 Release job checks out master instead of the tag ref, so artifacts may not match the tagged commit
.github/workflows/tagged-release.yml 78 continue-on-error: true on "Push files" step allows workflow to proceed with release/upload/store-submission even if git push fails
Files Reviewed (4 files)
  • .github/workflows/tagged-release.yml - 2 issues (previously flagged by qodo-code-review[bot]; still present on lines 52 and 78)
  • scripts/submit-stores.mjs - No issues (previous null-check issue on line 217 is now fixed)
  • package.json - No issues
  • tests/unit/release/submit-stores.test.mjs - No issues

Fix these issues in Kilo Cloud

Previous review (commit c8380f7)

Status: 3 Issues Found (Previously Flagged) | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
scripts/submit-stores.mjs 217 Missing null check for manifest before accessing manifest.version — if readJson returns null, a TypeError is thrown instead of the intended error
.github/workflows/tagged-release.yml 52 Release job checks out master instead of the tag ref (${{ github.ref }}), so artifacts may not match the tagged commit
.github/workflows/tagged-release.yml 78 continue-on-error: true on "Push files" step allows workflow to proceed with release/upload/store-submission even if git push fails
Files Reviewed (4 files)
  • .github/workflows/tagged-release.yml - 3 issues (2 pre-existing, 1 duplicate)
  • scripts/submit-stores.mjs - 1 issue (pre-existing)
  • package.json - No issues
  • tests/unit/release/submit-stores.test.mjs - No issues

All three issues were previously identified by other reviewers (gemini-code-assist[bot] and qodo-code-review[bot]). No new issues found in this review.

Fix these issues in Kilo Cloud


Reviewed by step-3.7-flash-20260528 · Input: 210.5K · Output: 32.8K · Cached: 739.8K

@PeterDaveHello
PeterDaveHello force-pushed the codex/fix-manual-release-workflow-vulnerability branch from c8380f7 to e08da38 Compare July 5, 2026 08:30
@PeterDaveHello
PeterDaveHello requested a review from Copilot July 5, 2026 17:27

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a preflight-only mode to the store submission script, allowing validation of release artifacts and manifest files without performing the actual upload or submission. It also refactors the submitStores function to support dependency injection, making it highly testable, and adds comprehensive unit tests. A review comment suggests merging the custom environment variables with process.env when spawning the child process to ensure critical system environment variables are preserved.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread scripts/submit-stores.mjs Outdated

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

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

Comment thread scripts/submit-stores.mjs Outdated
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit e08da38

@PeterDaveHello
PeterDaveHello force-pushed the codex/fix-manual-release-workflow-vulnerability branch from e08da38 to a87ab63 Compare July 5, 2026 17:45

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a preflight-only mode to the store submission script, allowing validation of release artifacts and the Firefox manifest without performing the actual submission or requiring store environment variables. It also refactors the submission script to support dependency injection, enabling comprehensive unit tests. The review feedback suggests refactoring 'runPublishExtension' to accept a 'baseEnv' option, which would avoid mutating the global 'process.env' in tests and simplify the test setup.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread scripts/submit-stores.mjs Outdated
Comment thread tests/unit/release/submit-stores.test.mjs
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit a87ab63

@PeterDaveHello
PeterDaveHello force-pushed the codex/fix-manual-release-workflow-vulnerability branch from a87ab63 to 2302190 Compare July 5, 2026 18:00

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

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

Comment thread .github/workflows/tagged-release.yml Outdated
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit d2d4f7b

PeterDaveHello and others added 10 commits August 26, 2026 02:51
Manual dispatches should validate release artifacts without invoking
publish-browser-extension's authenticated dry-run path.

Run workflow_dispatch as a read-only GitHub Actions preflight job with
no persisted checkout credentials. Keep real store submission on tag
pushes only. Cover artifact, manifest shape, process environment, and
credential boundaries with targeted tests.
Retry transient fetch and push races, abort conflicted rebases, and
surface failures in the step summary without blocking publication.
Reuse existing releases and clobber partial uploads so retries can
finish. Skip master sync when it already contains a newer manifest
version. Reject malformed store credentials before they reach publisher
code.
Treat missing version components as zero to prevent older tags from bypassing the master sync guard.

Leave completed releases untouched on workflow retries.
Keep manifest version values consistent with the release metadata path instead of silently accepting surrounding whitespace.
Reject prerelease tags before syncing manifest versions.

Build all browser archives before upload and distinguish missing releases from GitHub API failures during reruns.
Validate canonical manifest versions before syncing release tags.

Build artifacts before upload and record successful store submissions
so draft reruns can retry publication without resubmitting stores.
Run each store submission independently and persist its completion marker.

Reruns skip stores that already succeeded, keep Firefox metadata retryable,
and reject invalid master versions before release synchronization.
Limit artifact and manifest validation to the stores being submitted.\n\nPrevent new releases for superseded tags while allowing existing drafts to\nresume incomplete store submissions.
Reject all-zero Chromium versions and clear unselected ZIP variables.\n\nSerialize same-tag releases and skip superseded reruns before artifact\npublication.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@PeterDaveHello

Copy link
Copy Markdown
Member Author

/agentic_review

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

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

.github/workflows/tagged-release.yml:47

  • This group is unique per tag, so it does not serialize releases that target the same master branch and browser-store listings. If two version tags are pushed close together, both jobs can pass the superseded-version check and submit concurrently; the older package can then race or follow the newer package. Use a repository-wide release queue/lock around the master sync and store side effects.
      group: tagged-release-${{ github.ref_name }}

Comment thread scripts/submit-stores.mjs
Comment thread .github/workflows/tagged-release.yml
Comment thread .github/workflows/tagged-release.yml
Comment thread .github/workflows/tagged-release.yml
Comment thread .github/workflows/tagged-release.yml
Comment thread .github/workflows/tagged-release.yml
Comment thread .github/workflows/tagged-release.yml
Comment thread .github/workflows/tagged-release.yml
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit c56b695

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c56b695825

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/tagged-release.yml Outdated
if: github.event_name == 'push'
runs-on: macos-14
concurrency:
group: tagged-release-${{ github.ref_name }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Serialize store publication across release tags

When two different version tags are pushed close together, this tag-specific group lets both release jobs run concurrently. Fresh evidence beyond the resolved superseded-tag finding is that an older job can pass the monotonic check and push first, after which a newer job advances master while the older job continues without another version check. The bundled publish-extension --help describes its default command as submitting extensions for review, so the older job can reach the stores after the newer version and fail or attempt an out-of-order submission. Use a release-wide concurrency group or re-check the remote version immediately before store publication.

Useful? React with 👍 / 👎.

Comment thread .github/workflows/tagged-release.yml
@PeterDaveHello

Copy link
Copy Markdown
Member Author

/agentic_review

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

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

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

Comment thread .github/workflows/tagged-release.yml
Comment thread .github/workflows/tagged-release.yml
Comment thread .github/workflows/tagged-release.yml
Comment thread .github/workflows/tagged-release.yml
Comment thread .github/workflows/tagged-release.yml
Comment thread .github/workflows/tagged-release.yml
Comment thread .github/workflows/tagged-release.yml
Comment thread .github/workflows/tagged-release.yml
Comment thread .github/workflows/tagged-release.yml
Comment thread .github/workflows/tagged-release.yml
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 8ff04fd

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Security Review

Here are some automated security review suggestions for this pull request.

Reviewed commit: 8ff04fd2cc

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Comment thread .github/workflows/tagged-release.yml
Keep tag-triggered release reruns from replacing binaries already submitted
to a store.

Serialize master sync and reject equivalent version spellings before creating
a release.
@PeterDaveHello

Copy link
Copy Markdown
Member Author

/agentic_review

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

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

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

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 4b9ef50

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants