Skip to content

ci: support Intel and Windows release targets#89

Merged
Astro-Han merged 1 commit into
devfrom
codex/feat-release-intel-windows
Apr 21, 2026
Merged

ci: support Intel and Windows release targets#89
Astro-Han merged 1 commit into
devfrom
codex/feat-release-intel-windows

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Apr 21, 2026

Copy link
Copy Markdown
Owner

Summary

Add explicit release target selection to build.yml so the release workflow can build one platform/architecture per dispatch: macOS arm64, macOS x64, or Windows x64.

The workflow now rejects unsupported Windows combinations before matrix expansion, keeps macOS arm64 as the default, includes target and arch in the concurrency group, and uploads Windows packaged artifacts for inspection. Windows phase=full can publish through electron-builder, while Windows finalize is rejected because finalize is only for macOS notarization.

Review feedback is addressed by failing the Windows upload step when expected artifacts are missing, keeping Windows signing variables out until Azure authentication is wired, making the selector tests more robust, and adding focused docstrings for the changed workflow test helpers.

Windows artifacts from this PR remain unsigned unless signing is added in a later PR.

Why

The team needs a macOS Intel artifact for the current release work, and Windows distribution is now back on the release schedule. The old workflow only exposed arm64 and left x64/Windows matrix entries commented out, so it could not safely produce those release artifacts from the workflow UI.

Related Issue

Part of #86

Part of #87

How To Verify

ruby -e 'require "yaml"; YAML.load_file(".github/workflows/build.yml"); puts "ok"'
cd packages/opencode
bun test test/github/build-workflow.test.ts
bun test test/github
bun run typecheck

Additional checks:

git diff --check
actionlint .github/workflows/build.yml

actionlint still reports existing shellcheck warnings in unchanged macOS signing / summary blocks. The new target selection, matrix, concurrency, Windows packaging, and review-feedback fixes do not add new actionlint findings.

Fresh-eyes review loop completed with no remaining blocking findings.

Screenshots or Recordings

Not applicable. This is a release workflow change with no visible UI.

Checklist

  • I ran the relevant verification steps
  • I tested visible changes manually when needed
  • I am targeting the dev branch

Summary by CodeRabbit

  • New Features

    • Choose build target (macOS or Windows) and architecture (arm64 or x64); selection drives the build matrix and targeted builds.
  • Chores

    • Safer concurrency keys and dynamic build gating; snapshot/tag creation restricted to macOS submit runs.
    • Packaging publish behavior now depends on release phase; Windows artifacts uploaded with OS/arch-aware names.
  • Tests

    • Added integration and unit tests covering target selection, invalid combinations, output parsing, workflow validation, packaging, and artifact uploads.

@Astro-Han Astro-Han added ci Continuous integration / GitHub Actions windows Windows-specific P1 High priority platform Electron shell, OS integration, packaging, updater, signing, paths, and permissions labels Apr 21, 2026
@coderabbitai

coderabbitai Bot commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

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
📝 Walkthrough

Walkthrough

Adds workflow_dispatch inputs for target and extended arch choices; introduces a select-build-target job that validates inputs and emits matrix, target, and arch; downstream jobs (build-electron, create-snapshot-tag) now consume those outputs and have updated conditions and packaging/upload steps; tests and workflow-parser types were extended accordingly.

Changes

Cohort / File(s) Summary
Workflow Configuration
\.github/workflows/build.yml
Added workflow_dispatch input target (choices: macos,windows); added x64 to arch choices; expanded concurrency.group to include selected inputs; added select-build-target job that validates inputs and emits matrix, target, arch; build-electron now depends on select-build-target and uses strategy.matrix: fromJSON(...); create-snapshot-tag now runs only for phase=='submit' and target==macos; packaging publish flag and Windows artifact upload steps updated.
Workflow Test Suite
packages/opencode/test/github/build-workflow.test.ts
Replaced single assertion with execution-based tests: run select-build-target script across permutations (positive/negative), assert exit codes and parsed GITHUB_OUTPUT (matrix, target, arch); added negative-path tests for unsupported Windows/arch and invalid finalize phase; extended YAML assertions for concurrency.group, job needs/if wiring, step shell/env, and new upload artifact expectations; added helpers runSelectBuildTarget and parseGithubOutput.
Workflow Parser Types & Docs
packages/opencode/test/github/workflow-parser.ts
Extended exported types: WorkflowStep gains optional shell?: string; Workflow gains optional concurrency?: { group?: string; "cancel-in-progress"?: boolean }; added JSDoc comments. No runtime signature changes.

Sequence Diagram(s)

sequenceDiagram
    participant User as User (workflow_dispatch)
    participant GH as GitHub Actions
    participant Selector as select-build-target
    participant Builder as build-electron
    participant Snapshot as create-snapshot-tag
    participant Store as Artifact Storage

    User->>GH: trigger workflow (inputs: target, arch, phase)
    GH->>Selector: run selector job (validate inputs)
    Selector-->>GH: emit outputs (matrix, target, arch) via GITHUB_OUTPUT
    GH->>Builder: start build-electron using dynamic matrix (needs selector)
    GH->>Snapshot: evaluate snapshot creation (needs selector, if phase==submit && target==macos)
    Builder->>Builder: package app (publish_flag depends on phase)
    Builder->>Store: upload packaged artifacts (OS/arch labeled)
    Snapshot->>GH: create snapshot tag when gated conditions met
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

enhancement

Poem

A rabbit taps keys in the CI glade, 🐇
Picks target, arch — a hop-scoped parade,
Validates options, emits a tiny matrix,
Builds, packages, and uploads with neat tricks,
Hooray — the workflow hops into flight!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'ci: support Intel and Windows release targets' directly reflects the main change: extending the CI workflow to support additional release targets (Intel/x64 and Windows).
Description check ✅ Passed The PR description covers all template sections: Summary explains the changes, Why provides context and rationale, Related Issue links to #86 and #87, How To Verify lists comprehensive verification commands, and Checklist items are marked complete.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/feat-release-intel-windows

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

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

Code Review

This pull request enhances the GitHub workflow tests by adding validation for macOS and Windows release matrices and updating the workflow parser to support concurrency and shell properties. It introduces a helper function to execute and verify workflow scripts locally. Feedback includes improving the robustness of script extraction by avoiding hardcoded indices, refining bash execution flags to better simulate GitHub Actions, fixing potential parsing errors in output handling, and ensuring temporary directory cleanup using a try-finally block.

Comment thread packages/opencode/test/github/build-workflow.test.ts Outdated
Comment thread packages/opencode/test/github/build-workflow.test.ts Outdated
Comment thread packages/opencode/test/github/build-workflow.test.ts Outdated
Comment thread packages/opencode/test/github/build-workflow.test.ts Outdated

@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: 9bfd2cd661

ℹ️ 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/build.yml Outdated

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/opencode/test/github/build-workflow.test.ts (2)

117-123: Lookup the select step by id instead of by position.

Reading steps[0] makes this helper fail on harmless workflow edits like inserting a setup step before the selector. Resolve the step with id == "select" and read its run field from there.

Suggested fix
   const ruby = String.raw`
     require "yaml"
 
     data = YAML.load_file(ARGV[0])
-    puts data["jobs"]["select-build-target"]["steps"][0]["run"]
+    step = data["jobs"]["select-build-target"]["steps"].find { |entry| entry["id"] == "select" }
+    raise "Missing select-build-target step with id=select" unless step
+    puts step["run"]
   `
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/opencode/test/github/build-workflow.test.ts` around lines 117 - 123,
The test currently extracts the selector step by position using a small Ruby
snippet that reads data["jobs"]["select-build-target"]["steps"][0]["run"];
change that logic to locate the step object whose id == "select" inside
data["jobs"]["select-build-target"]["steps"] and then read its "run" field
(i.e., iterate or find the step with step["id"] == "select" and return
step["run"]) so the helper is robust to inserted steps; update the Ruby snippet
(the variable ruby used with execFileSync) to perform this lookup and return the
run string.

124-150: Use the shared test tmpdir helper here.

This manual temp-dir lifecycle bypasses the repo fixture cleanup and can leak the directory if parsing throws before Line 150. Please switch this helper to tmpdir/await using, or at least move the cleanup into a finally.

As per coding guidelines, "Use the tmpdir function from fixture/fixture.ts to create temporary directories for tests with automatic cleanup. Use await using syntax to ensure automatic cleanup when the variable goes out of scope."

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

In `@packages/opencode/test/github/build-workflow.test.ts` around lines 124 - 150,
Replace the manual temp dir lifecycle (tmp created by fs.mkdtempSync and later
fs.rmSync) with the shared test helper tmpdir from fixture/fixture.ts: create
the temp dir via await using tmp = await tmpdir("pawwork-build-target-") (or the
helper's exact API), build outputPath from that tmp, keep the spawnSync call and
subsequent reading of outputPath unchanged, and remove the explicit fs.rmSync
cleanup so the tmpdir helper automatically cleans up; if you cannot use await
using, wrap the mkdtempSync/spawnSync/read in a try/finally and move fs.rmSync
into the finally to guarantee cleanup.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/build.yml:
- Around line 739-747: The upload step "Upload packaged app artifact" currently
uses actions/upload-artifact@... which only warns when globs match nothing;
update that step's inputs (the with: block for the actions/upload-artifact step)
to include the if-no-files-found option set to "error" so the job fails if the
Windows artifact globs (packages/desktop-electron/dist/*.exe, *.exe.blockmap,
latest*.yml) are missing; locate the step by its name or the
actions/upload-artifact usage and add if-no-files-found: error.

---

Nitpick comments:
In `@packages/opencode/test/github/build-workflow.test.ts`:
- Around line 117-123: The test currently extracts the selector step by position
using a small Ruby snippet that reads
data["jobs"]["select-build-target"]["steps"][0]["run"]; change that logic to
locate the step object whose id == "select" inside
data["jobs"]["select-build-target"]["steps"] and then read its "run" field
(i.e., iterate or find the step with step["id"] == "select" and return
step["run"]) so the helper is robust to inserted steps; update the Ruby snippet
(the variable ruby used with execFileSync) to perform this lookup and return the
run string.
- Around line 124-150: Replace the manual temp dir lifecycle (tmp created by
fs.mkdtempSync and later fs.rmSync) with the shared test helper tmpdir from
fixture/fixture.ts: create the temp dir via await using tmp = await
tmpdir("pawwork-build-target-") (or the helper's exact API), build outputPath
from that tmp, keep the spawnSync call and subsequent reading of outputPath
unchanged, and remove the explicit fs.rmSync cleanup so the tmpdir helper
automatically cleans up; if you cannot use await using, wrap the
mkdtempSync/spawnSync/read in a try/finally and move fs.rmSync into the finally
to guarantee cleanup.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1a006ceb-9b72-4d24-97ee-3d2eb681e739

📥 Commits

Reviewing files that changed from the base of the PR and between 6947d7b and 9bfd2cd.

📒 Files selected for processing (3)
  • .github/workflows/build.yml
  • packages/opencode/test/github/build-workflow.test.ts
  • packages/opencode/test/github/workflow-parser.ts

Comment thread .github/workflows/build.yml
@Astro-Han Astro-Han force-pushed the codex/feat-release-intel-windows branch from 9bfd2cd to 18a2daa Compare April 21, 2026 08:55

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

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

Inline comments:
In @.github/workflows/build.yml:
- Around line 740-745: The artifact upload step currently uses runner.os in the
job name and allows non-macOS runs but the path patterns under path only match
Windows (*.exe, *.exe.blockmap, latest*.yml), causing failures when Linux runs
occur; either restrict the step to Windows by changing the conditional to
runner.os == 'Windows' or make the artifact path conditional on runner.os (e.g.,
split into separate steps or use conditional path patterns) and keep the
if-no-files-found: error behavior; update the step that defines name,
if-no-files-found and path so the runner.os check aligns with the
Windows-specific patterns.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fb09f1bc-2339-4db5-aa2c-8e31ea8f21c3

📥 Commits

Reviewing files that changed from the base of the PR and between 9bfd2cd and 18a2daa.

📒 Files selected for processing (3)
  • .github/workflows/build.yml
  • packages/opencode/test/github/build-workflow.test.ts
  • packages/opencode/test/github/workflow-parser.ts

Comment thread .github/workflows/build.yml
@Astro-Han Astro-Han force-pushed the codex/feat-release-intel-windows branch from 18a2daa to a60f37a Compare April 21, 2026 09:01

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

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

Inline comments:
In @.github/workflows/build.yml:
- Around line 100-103: Update the x64 branch so the host uses an explicit Intel
macOS runner instead of macos-latest: change host="macos-latest" to
host="macos-15-intel" in the x64 case where platform_flag="--mac --x64" is set;
also update the corresponding test expectation in build-workflow.test.ts that
asserts the macOS runner for the x64 target to expect "macos-15-intel" now.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f005e3ed-f9db-4856-845f-507636999dbd

📥 Commits

Reviewing files that changed from the base of the PR and between 18a2daa and a60f37a.

📒 Files selected for processing (3)
  • .github/workflows/build.yml
  • packages/opencode/test/github/build-workflow.test.ts
  • packages/opencode/test/github/workflow-parser.ts

Comment thread .github/workflows/build.yml
@Astro-Han Astro-Han force-pushed the codex/feat-release-intel-windows branch from a60f37a to 8161695 Compare April 21, 2026 09:16
@Astro-Han

Copy link
Copy Markdown
Owner Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Apr 21, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

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

Inline comments:
In @.github/workflows/build.yml:
- Around line 205-206: The workflow currently sets SELECTED_ARCH from
inputs.arch while SELECTED_TARGET already comes from
needs.select-build-target.outputs.target; to avoid drift, change SELECTED_ARCH
to use the selector output as the single source of truth (use
needs.select-build-target.outputs.target or a dedicated outputs.arch from the
select job) instead of inputs.arch so both SELECTED_TARGET and SELECTED_ARCH are
derived from the selector output (update SELECTED_ARCH assignment where it's
defined to reference the selector output symbol rather than inputs.arch).

In `@packages/opencode/test/github/build-workflow.test.ts`:
- Around line 12-49: The tests that spawn child processes and touch the
filesystem (those calling runSelectBuildTarget and the parseGithubOutput case,
e.g. the "selects the macOS x64 release matrix", "selects the Windows x64
release matrix", "rejects unsupported Windows release combinations", and
"ignores malformed GitHub output lines" tests) must be executed under the live
test harness; replace test(...) with the live variant provided by the file-level
testEffect harness (use it.live(...) or testEffect(...).live as used elsewhere)
so these cases run as live tests rather than normal unit tests; ensure each test
that calls runSelectBuildTarget or relies on real child-process/IO behavior is
converted to use the live wrapper.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 84e09f73-c1d9-4546-8dae-a6bb370ad39a

📥 Commits

Reviewing files that changed from the base of the PR and between a60f37a and 8161695.

📒 Files selected for processing (3)
  • .github/workflows/build.yml
  • packages/opencode/test/github/build-workflow.test.ts
  • packages/opencode/test/github/workflow-parser.ts

Comment thread .github/workflows/build.yml Outdated
Comment thread packages/opencode/test/github/build-workflow.test.ts Outdated
@Astro-Han

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

ℹ️ 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".

@Astro-Han Astro-Han force-pushed the codex/feat-release-intel-windows branch from 8161695 to e683bdd Compare April 21, 2026 10:04

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

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

Inline comments:
In @.github/workflows/build.yml:
- Around line 69-71: Add `${{ inputs.channel }}` into the concurrency group
string in the workflow so the key becomes ${{ github.workflow }}-${{ github.ref
}}-${{ inputs.phase || 'submit' }}-${{ inputs.channel }}-${{ inputs.target ||
'macos' }}-${{ inputs.arch || 'arm64' }}, and update the corresponding
expectation in build-workflow.test.ts that asserts the concurrency group (the
test that checks the workflow concurrency string) to include the channel token
in the same position so tests match the new group format.

In `@packages/opencode/test/github/build-workflow.test.ts`:
- Around line 76-78: The test currently asserts the total count of
upload-artifact steps by checking uploadArtifactSteps.length (variable
uploadArtifactSteps created via steps.filter on step.uses), which is brittle;
instead locate the Windows-specific upload step(s) by filtering for the expected
step.name or other key fields (e.g., name === "Upload Windows artifact" or the
step.with.key fields) and assert those properties (name, uses, and the
with.path/with.name values) rather than asserting toHaveLength(3); update both
occurrences (around the uploadArtifactSteps filter and the similar block at
lines 118-123) to find and assert the named step(s) and their key fields.
- Around line 14-62: Several tests use Effect.promise(...) and Effect.sync(...)
directly; wrap their bodies in Effect.gen(function* () { ... }) instead. For
each test referencing runSelectBuildTarget or parseGithubOutput, replace the
Effect.promise(async () => { ... }) and Effect.sync(() => { ... }) callbacks
with Effect.gen(function* () { ... }) and move the existing async/sync logic
into that generator body so the test follows the repository's Effect test
pattern (keep the same assertions and calls to
runSelectBuildTarget/parseGithubOutput, just relocate them inside the
generator).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ef1e1ab9-0e95-4701-84d3-32a226a5da9c

📥 Commits

Reviewing files that changed from the base of the PR and between 8161695 and e683bdd.

📒 Files selected for processing (3)
  • .github/workflows/build.yml
  • packages/opencode/test/github/build-workflow.test.ts
  • packages/opencode/test/github/workflow-parser.ts

Comment thread .github/workflows/build.yml
Comment thread packages/opencode/test/github/build-workflow.test.ts Outdated
Comment thread packages/opencode/test/github/build-workflow.test.ts Outdated
@Astro-Han Astro-Han force-pushed the codex/feat-release-intel-windows branch from e683bdd to 168f237 Compare April 21, 2026 10:20
@Astro-Han Astro-Han merged commit 4fed0ca into dev Apr 21, 2026
14 checks passed
@Astro-Han Astro-Han deleted the codex/feat-release-intel-windows branch April 21, 2026 10:30
@coderabbitai coderabbitai Bot mentioned this pull request May 3, 2026
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci Continuous integration / GitHub Actions P1 High priority platform Electron shell, OS integration, packaging, updater, signing, paths, and permissions windows Windows-specific

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant