mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
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:
@@ -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'
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user