ci(adhoc): start the 12-vCPU Mac packaging jobs after template qualification (#34327)

Both arch jobs overlapped ~2.5 min of setup with qualification, then polled
for the template for 400-560 s on the most expensive runner we use.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
OrcaWin
2026-10-27 02:18:24 -07:00
committed by GitHub
co-authored by OrcaWin
parent 3b7ee71b0f
commit 64090416e3
3 changed files with 64 additions and 71 deletions
+10 -26
View File
@@ -250,11 +250,19 @@ jobs:
echo "tag=$TAG" >>"$GITHUB_OUTPUT"
build-adhoc-mac-arch:
needs: [resolve-ref, orcad-template-support, release-javascript, prepare-adhoc-mac-release]
# Template qualification gates packaging after desktop preparation.
needs:
[
resolve-ref,
orcad-template-support,
orcad-template,
release-javascript,
prepare-adhoc-mac-release
]
# Start after template qualification: overlapping ~2.5 min of preparation left both 12-vCPU Macs idle ~7 min.
if: >-
!cancelled() && github.repository == 'stablyai/orca' &&
needs.orcad-template-support.result == 'success' &&
(needs.orcad-template.result == 'success' || needs.orcad-template-support.outputs.ships != 'true') &&
needs.release-javascript.result == 'success' &&
needs.prepare-adhoc-mac-release.result == 'success'
# Signing environment must restrict deployments to main after MAC_CERTS/password, APPLE_ID/app password/team and hourly App secrets move there; referencing it alone enforces nothing.
@@ -374,30 +382,6 @@ jobs:
# Leave build identity unset: telemetry accepts only official stable/rc, so branch artifacts stay silent.
ORCA_DIAGNOSTICS_TOKEN_URL: https://www.onorca.dev/diagnostics/token
- name: Wait for the qualified orcad template
if: needs.orcad-template-support.outputs.ships == 'true'
uses: actions/github-script@v8
with:
script: |
const deadline = Date.now() + 30 * 60_000
while (Date.now() < deadline) {
const jobs = await github.paginate(github.rest.actions.listJobsForWorkflowRun, {
...context.repo, run_id: context.runId, filter: 'latest', per_page: 100
})
const lanes = jobs.filter(job => job.name.startsWith('orcad-template / '))
const failed = lanes.find(job => job.status === 'completed' &&
['failure', 'cancelled', 'timed_out', 'action_required', 'startup_failure'].includes(job.conclusion))
if (failed) throw new Error(`Template qualification failed: ${failed.name}`)
const artifacts = await github.paginate(github.rest.actions.listWorkflowRunArtifacts, {
...context.repo, run_id: context.runId, per_page: 100
})
const ready = artifacts.some(artifact => artifact.name === 'orcad-template' && !artifact.expired)
const completed = lanes.length > 0 && lanes.every(job => job.status === 'completed')
if (ready && (process.env.WAIT_FOR_TEMPLATE_COMPLETION !== '1' || completed)) return
await new Promise(resolve => setTimeout(resolve, 15_000))
}
throw new Error('Timed out waiting for the qualified orcad template')
# 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'
+50 -42
View File
@@ -5,7 +5,7 @@ import { parse } from 'yaml'
const adhoc = parse(readFileSync('.github/workflows/adhoc-mac-build.yml', 'utf8'))
const publisher = parse(readFileSync('.github/workflows/dev-channel-win-publish.yml', 'utf8'))
const windows = parse(readFileSync('.github/workflows/dev-channel-win-build.yml', 'utf8'))
const macSteps = adhoc.jobs['build-adhoc-mac-arch'].steps
const macBuild = adhoc.jobs['build-adhoc-mac-arch']
const finalSteps = adhoc.jobs['build-adhoc-mac'].steps
const publishSteps = publisher.jobs['publish-win'].steps
const macWait = publishSteps.find((step) => step.name === 'Wait for successful macOS publication')
@@ -53,50 +53,58 @@ const job = (name, conclusion) => ({
conclusion
})
describe.each([
['Mac', macSteps],
['Windows', windows.jobs['build-win'].steps]
])('%s release waits retain qualification and publication gates', (_platform, buildSteps) => {
const templateWait = buildSteps.find(
(step) => step.name === 'Wait for the qualified orcad template'
it('starts paid Mac packaging only after template qualification succeeds', () => {
expect(macBuild.needs).toContain('orcad-template')
expect(macBuild.if).toContain("needs.orcad-template.result == 'success'")
expect(macBuild.steps.some((step) => step.name === 'Wait for the qualified orcad template')).toBe(
false
)
it('allows desktop setup first, but waits for a qualified artifact from this run', async () => {
const { result, calls } = execute(templateWait, [
{ jobs: [job('orcad-template / cache', 'success')] },
{ jobs: [job('orcad-template / qualify / persistence (windows-11-arm)')] },
{ artifacts: [{ name: 'orcad-template', expired: true }] },
{ artifacts: [{ name: 'orcad-template', expired: false }] }
])
await result
expect(calls.filter((call) => call.endpoint === 'artifacts')).toHaveLength(4)
expect(calls.every((call) => call.input.run_id === 42)).toBe(true)
expect(buildSteps.indexOf(templateWait)).toBeGreaterThan(
buildSteps.findIndex((step) => step.name === 'Build app')
)
expect(buildSteps.indexOf(templateWait)).toBeLessThan(
buildSteps.findIndex((step) => step.name === 'Download the orcad deployment template')
)
})
it.each(['failure', 'cancelled', 'timed_out', 'action_required', 'startup_failure'])(
'refuses to package after template qualification ends with %s',
async (conclusion) => {
await expect(
execute(templateWait, [
{
jobs: [job('orcad-template / qualify / persistence (windows-11-arm)', conclusion)],
artifacts: [{ name: 'orcad-template', expired: false }]
}
]).result
).rejects.toThrow('Template qualification failed')
}
)
it('times out when no qualified artifact is produced', async () => {
await expect(execute(templateWait, [{}]).result).rejects.toThrow('Timed out')
})
})
describe.each([['Windows', windows.jobs['build-win'].steps]])(
'%s release waits retain qualification and publication gates',
(_platform, buildSteps) => {
const templateWait = buildSteps.find(
(step) => step.name === 'Wait for the qualified orcad template'
)
it('allows desktop setup first, but waits for a qualified artifact from this run', async () => {
const { result, calls } = execute(templateWait, [
{ jobs: [job('orcad-template / cache', 'success')] },
{ jobs: [job('orcad-template / qualify / persistence (windows-11-arm)')] },
{ artifacts: [{ name: 'orcad-template', expired: true }] },
{ artifacts: [{ name: 'orcad-template', expired: false }] }
])
await result
expect(calls.filter((call) => call.endpoint === 'artifacts')).toHaveLength(4)
expect(calls.every((call) => call.input.run_id === 42)).toBe(true)
expect(buildSteps.indexOf(templateWait)).toBeGreaterThan(
buildSteps.findIndex((step) => step.name === 'Build app')
)
expect(buildSteps.indexOf(templateWait)).toBeLessThan(
buildSteps.findIndex((step) => step.name === 'Download the orcad deployment template')
)
})
it.each(['failure', 'cancelled', 'timed_out', 'action_required', 'startup_failure'])(
'refuses to package after template qualification ends with %s',
async (conclusion) => {
await expect(
execute(templateWait, [
{
jobs: [job('orcad-template / qualify / persistence (windows-11-arm)', conclusion)],
artifacts: [{ name: 'orcad-template', expired: false }]
}
]).result
).rejects.toThrow('Template qualification failed')
}
)
it('times out when no qualified artifact is produced', async () => {
await expect(execute(templateWait, [{}]).result).rejects.toThrow('Timed out')
})
}
)
it('keeps the release a draft until qualification and its cleanup finish', async () => {
const final = finalSteps.find(
(step) => step.name === 'Confirm final template qualification before publication'
@@ -25,9 +25,10 @@ function qualification(template = 'success', ships = 'true') {
}
describe('adhoc Windows compilation overlaps Mac without publishing early', () => {
it('starts both platforms during qualification without a Mac dependency', () => {
expect(mac.needs).toEqual([...windows.needs, 'prepare-adhoc-mac-release'])
expect(mac.needs).not.toContain('orcad-template')
it('starts Windows during qualification without a Mac dependency', () => {
expect(mac.needs).toEqual(
expect.arrayContaining([...windows.needs, 'orcad-template', 'prepare-adhoc-mac-release'])
)
expect(windows.needs).not.toContain('build-adhoc-mac')
expect(windows.with.stage_only).toBe(true)
expect(windows.with.fast_release).toBe(true)