Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 67 additions & 3 deletions .github/workflows/adhoc-mac-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ name: Adhoc macOS + Windows Dev Build
#
# Deliberately narrow scope:
# - macOS and Windows desktop installers. Linux keeps using RC/stable.
# - No tests, no lint, no e2e. PR CI and release-cut remain the gates.
# - No tests, no lint, no e2e. PR CI and release-cut remain the gates. The one
# exception is the orcad template: like release-cut, it is merged from the
# node-server lanes that build and qualify each SSH target's slot.
# - macOS is signed and notarized so TCC grants survive updates.
# - Windows is unsigned; the published release notes explain the one-time
# SmartScreen/manual-install requirement.
Expand Down Expand Up @@ -93,9 +95,59 @@ jobs:
with:
ref: ${{ inputs.ref || github.ref_name }}

build-adhoc-mac:
needs: relay-windows-process-tree
# Why: a branch cut before the orcad template landed has none to build or ship.
orcad-template-support:
if: github.repository == 'stablyai/orca'
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
outputs:
ships: ${{ steps.detect.outputs.ships }}
steps:
- name: Checkout the template packager only
uses: actions/checkout@v6
with:
ref: ${{ inputs.ref || github.ref_name }}
sparse-checkout: |
/config/scripts/packaged-orcad-template.cjs
sparse-checkout-cone-mode: false
persist-credentials: false
- name: Detect whether the ref ships the orcad template
id: detect
shell: bash
run: |
if [[ -f config/scripts/packaged-orcad-template.cjs ]]; then
echo "ships=true" >>"$GITHUB_OUTPUT"
else
echo "ships=false" >>"$GITHUB_OUTPUT"
echo "::notice::This ref predates the orcad template; the build ships without it."
fi

# Design D2, as release-cut does: every desktop build ships the orcad template (server JS plus
# every target's addons), merged from the node-server lanes that qualify each slot at this ref.
# Without it an adhoc build cannot deploy managed orcad to an SSH host. No secrets, like the
# relay job, and the mac job vets the ref before anything is signed.
orcad-template:
needs: orcad-template-support
if: needs.orcad-template-support.outputs.ships == 'true'
permissions:
contents: read
uses: ./.github/workflows/node-server-tests.yml
with:
ref: ${{ inputs.ref || github.ref_name }}

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.

The mac app build pins the vetted commit (ref: ${{ steps.vetted.outputs.sha }}), but the template is built from the mutable inputs.ref || github.ref_name. A push landing between the template checkout and the mac job's vetting can pair an app with a template from a different commit — and the template's addons and server JS are what get deployed to remote hosts. The relay job has the same shape, so this is pre-existing, but the template makes it a new cross-commit coupling.

Technical details
# Template built from a mutable ref while the app is pinned

## Affected sites
- `.github/workflows/adhoc-mac-build.yml:138` — template call uses the branch name
- `.github/workflows/adhoc-mac-build.yml:94-96` — relay build uses the branch name too
- `.github/workflows/adhoc-mac-build.yml:227-241` — app build pins `steps.vetted.outputs.sha`

## Required outcome
- Template and relay builds resolve the same immutable commit the app build does, so a mid-run push cannot produce a mixed-commit adhoc build.

## Open questions for the human
- Is pinning the template worth restructuring the job graph (resolve the SHA before the parallel jobs)? The relay job would need the same treatment to be fully consistent.

build_template: true

build-adhoc-mac:
needs: [relay-windows-process-tree, orcad-template-support, orcad-template]
# Why not the implicit success(): a ref without the orcad template skips that job on purpose.
if: >-
!cancelled() && github.repository == 'stablyai/orca' &&
needs.relay-windows-process-tree.result == 'success' &&
needs.orcad-template-support.result == 'success' &&
(needs.orcad-template.result == 'success' ||
(needs.orcad-template.result == 'skipped' &&
needs.orcad-template-support.outputs.ships == 'false'))
# Why an environment: it gives the signing/notary/App secrets somewhere to
# live that a stale copy of this workflow on an old branch cannot reach.
# Referencing it is a no-op until repo settings give it teeth; the intended
Expand All @@ -109,6 +161,7 @@ jobs:
version: ${{ steps.adhoc.outputs.version }}
head_sha: ${{ steps.adhoc.outputs.head_sha }}
published: ${{ steps.publish_live.outcome == 'success' && 'true' || 'false' }}
ships_orcad_template: ${{ needs.orcad-template-support.outputs.ships }}
runs-on: blacksmith-6vcpu-macos-15
# Why 150: it must exceed the worst case the retry budgets below can produce
# (install 3x10 + publish 2x45 = 120, plus ~25 for checkout/build/verify), or
Expand Down Expand Up @@ -292,6 +345,14 @@ jobs:
# sshd's job for a standard user on a Windows SSH host.
ORCA_REQUIRE_RELAY_NATIVE_ADDONS: x64,arm64

# After the app build so nothing that cleans out/ can drop it; electron-builder ships it.
- name: Download the orcad deployment template
if: needs.orcad-template-support.outputs.ships == 'true'
uses: actions/download-artifact@v8
with:
name: orcad-template
path: out/orcad-template

# Why the token is minted here and not at the top: installation tokens live
# one hour, everything before this point writes nothing, and the notary round
# trip inside the publish step can be tens of minutes. Minting after the build
Expand Down Expand Up @@ -366,6 +427,8 @@ jobs:
GH_TOKEN: ${{ steps.app_token.outputs.token }}
ORCA_ADHOC_BUILD_VERSION: ${{ steps.adhoc.outputs.version }}
ORCA_BUILD_COMMIT: ${{ steps.adhoc.outputs.commit }}
# beforePack and afterPack fail the package when the template is absent.
ORCA_REQUIRE_ORCAD_TEMPLATE: ${{ needs.orcad-template-support.outputs.ships == 'true' && '1' || '' }}
CSC_LINK: ${{ secrets.MAC_CERTS }}
CSC_KEY_PASSWORD: ${{ secrets.MAC_CERTS_PASSWORD }}
# Why all three: electron-builder's notarize step authenticates to the
Expand Down Expand Up @@ -514,3 +577,4 @@ jobs:
tag: ${{ needs.build-adhoc-mac.outputs.tag }}
ref: ${{ needs.build-adhoc-mac.outputs.head_sha }}
version: ${{ needs.build-adhoc-mac.outputs.version }}
orcad_template: ${{ needs.build-adhoc-mac.outputs.ships_orcad_template == 'true' }}
15 changes: 15 additions & 0 deletions .github/workflows/dev-channel-win-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ on:
description: Version to package, without the leading v
required: true
type: string
orcad_template:
description: Ship the orcad-template artifact the calling run built (adhoc does; hourly and daily do not yet)
required: false
type: boolean
default: false
Comment on lines +61 to +65

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.

The new orcad_template input exists only under workflow_call, so a manual workflow_dispatch rebuild of the Windows leg for an adhoc tag can't fetch the caller run's artifact and silently packages without the template (ORCA_REQUIRE_ORCAD_TEMPLATE stays empty). Since the file header advertises standalone dispatch for rebuilding an existing tag, that recovery path now produces a Windows installer inconsistent with the mac installer in the same release. If it should keep the template, it needs a source-run input plus actions: read; otherwise a header note would set expectations.

Technical details
# Manual Windows rebuild drops the template

## Affected sites
- `.github/workflows/dev-channel-win-build.yml:61-65` — `orcad_template` declared only under `workflow_call`
- `.github/workflows/dev-channel-win-build.yml:273-278` — download gated on `inputs.orcad_template`
- `.github/workflows/dev-channel-win-build.yml:318` — `ORCA_REQUIRE_ORCAD_TEMPLATE` empty on manual dispatch

## Required outcome
- Either the manual path can obtain the `orcad-template` artifact (needs `actions: read` and a source run id, as `release-mac-build.yml` does), or the header's “rebuild a Windows artifact for an existing tag” is qualified for template-shipping channels.

workflow_dispatch:
inputs:
channel:
Expand Down Expand Up @@ -264,6 +269,14 @@ jobs:
# is correct for unvetted artifacts. Same as the mac dev channels.
ORCA_DIAGNOSTICS_TOKEN_URL: https://www.onorca.dev/diagnostics/token

# After the app build so nothing that cleans out/ can drop it; electron-builder ships it.
- name: Download the orcad deployment template
if: inputs.orcad_template
uses: actions/download-artifact@v8
with:
name: orcad-template
path: out/orcad-template

# Why the token is minted here and not at the top: installation tokens live
# one hour and nothing before this point writes anything.
- name: Mint dev channel repo token
Expand Down Expand Up @@ -301,6 +314,8 @@ jobs:
env:
GH_TOKEN: ${{ steps.app_token.outputs.token }}
ORCA_BUILD_COMMIT: ${{ inputs.ref }}
# beforePack and afterPack fail the package when the template is absent.
ORCA_REQUIRE_ORCAD_TEMPLATE: ${{ inputs.orcad_template && '1' || '' }}
# Why: electron-publish refuses to upload into a release published more
# than two hours ago (gitHubPublisher.getOrCreateRelease). The mac leg
# publishes the draft live as soon as *it* finishes, so a slow notary
Expand Down
Loading