forked from raphaeltm/simple-agent-manager
-
Notifications
You must be signed in to change notification settings - Fork 0
136 lines (130 loc) · 4.98 KB
/
Copy pathdeploy.yml
File metadata and controls
136 lines (130 loc) · 4.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
name: Deploy Production
on:
# Canonical repo auto-deploys after successful main CI. Forked self-host
# installs should update by manually running this workflow on main.
workflow_run:
workflows: ['CI']
types: [completed]
workflow_dispatch:
inputs:
target_commit_sha:
description: 'Exact 40-character commit SHA to deploy'
required: true
type: string
emergency_override_reason:
description: 'Audited emergency reason to deploy without verified CI on the exact SHA'
required: false
type: string
skip_agent:
description: 'Skip VM Agent build and upload'
required: false
type: boolean
default: false
dry_run:
description: 'Preview changes without applying'
required: false
type: boolean
default: false
permissions:
contents: read
actions: read
# Serialize only trusted production candidates. Every no-op/untrusted event gets
# a unique group so it cannot replace GitHub's single pending production run.
concurrency:
group: >-
${{
(
(github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main') ||
(
github.event_name == 'workflow_run' &&
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'push' &&
github.event.workflow_run.head_branch == 'main' &&
github.event.workflow_run.head_repository.full_name == github.repository
)
) &&
'deploy-production' ||
format('deploy-production-noop-{0}', github.run_id)
}}
cancel-in-progress: false
jobs:
validate-manual-dispatch:
name: Validate manual production target
if: ${{ github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' }}
runs-on: ubuntu-latest
outputs:
deploy_sha: ${{ steps.gate.outputs.deploy_sha }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup pnpm
uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '22'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Validate exact SHA and CI gate
id: gate
run: pnpm tsx scripts/deploy/validate-production-dispatch.ts
env:
GITHUB_TOKEN: ${{ github.token }}
TARGET_COMMIT_SHA: ${{ inputs.target_commit_sha }}
EMERGENCY_OVERRIDE_REASON: ${{ inputs.emergency_override_reason }}
PRODUCTION_DEPLOY_OVERRIDE_REASON_MIN_LENGTH: ${{ vars.PRODUCTION_DEPLOY_OVERRIDE_REASON_MIN_LENGTH }}
validate-automatic-dispatch:
name: Validate automatic production target
if: >-
github.event_name == 'workflow_run' &&
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'push' &&
github.event.workflow_run.head_branch == 'main' &&
github.event.workflow_run.head_repository.full_name == github.repository
runs-on: ubuntu-latest
outputs:
deploy_sha: ${{ steps.gate.outputs.deploy_sha }}
steps:
- name: Checkout trusted current main
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: refs/heads/main
- name: Setup pnpm
uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '22'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Re-verify current main after deployment queue
id: gate
run: pnpm tsx scripts/deploy/validate-production-dispatch.ts
env:
GITHUB_TOKEN: ${{ github.token }}
TARGET_COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
# Gate only on the GitHub Actions CI workflow result. SonarCloud is a
# separate GitHub App check and must not suppress production deploys.
deploy:
needs: [validate-manual-dispatch, validate-automatic-dispatch]
if: >-
always() &&
(
(
github.event_name == 'workflow_dispatch' &&
needs.validate-manual-dispatch.result == 'success'
) ||
(
github.event_name == 'workflow_run' &&
needs.validate-automatic-dispatch.result == 'success'
)
)
uses: ./.github/workflows/deploy-reusable.yml
with:
environment: production
target_commit_sha: ${{ github.event_name == 'workflow_dispatch' && needs.validate-manual-dispatch.outputs.deploy_sha || needs.validate-automatic-dispatch.outputs.deploy_sha }}
skip_agent: ${{ inputs.skip_agent || false }}
dry_run: ${{ inputs.dry_run || false }}
secrets: inherit