Repository navigation
142 lines (130 loc) · 4.66 KB
/
Copy pathpromotion.yml
File metadata and controls
142 lines (130 loc) · 4.66 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
137
138
139
140
141
142
name: Promote Vapi resources
on:
push:
branches: [main]
paths:
- promotion.yml
- resources/**
workflow_dispatch:
inputs:
pipeline:
description: Pipeline name from promotion.yml
required: false
type: string
from:
description: Source org (requires a destination org)
required: false
type: string
to:
description: Destination org (requires a source org)
required: false
type: string
permissions:
contents: write
concurrency:
group: vapi-promotion
cancel-in-progress: false
jobs:
promote:
if: >-
github.event_name == 'workflow_dispatch' ||
(vars.VAPI_PROMOTION_ENABLED == 'true' &&
!contains(github.event.head_commit.message, '[skip promotion]'))
runs-on: ubuntu-latest
env:
VAPI_PROMOTION_TOKENS: ${{ secrets.VAPI_PROMOTION_TOKENS }}
PIPELINE: ${{ inputs.pipeline }}
SOURCE_ORG: ${{ inputs.from }}
TARGET_ORG: ${{ inputs.to }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: main
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- name: Reconcile configured promotions
id: promotion
# A safety net only, on the step rather than the job so a timeout
# still leaves the always() commit step below time to run. Gate
# checks bound themselves (promotionGateRun's deadline), and their
# combined budget is checked against 300 minutes when the config
# loads, so this cap doesn't cut short a long ungated promotion.
timeout-minutes: 330
shell: bash
run: |
set -euo pipefail
test -f promotion.yml || {
echo "promotion.yml is required; copy promotion.example.yml and customize it."
exit 1
}
test -n "$VAPI_PROMOTION_TOKENS" || {
echo "The VAPI_PROMOTION_TOKENS repository secret is required."
exit 1
}
if [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then
supplied=0
[[ -n "$PIPELINE" ]] && ((supplied += 1))
[[ -n "$SOURCE_ORG" ]] && ((supplied += 1))
[[ -n "$TARGET_ORG" ]] && ((supplied += 1))
[[ "$supplied" == 0 || "$supplied" == 3 ]] || {
echo "Provide pipeline, from, and to together, or leave all three blank."
exit 1
}
args=(--apply)
if [[ "$supplied" == 3 ]]; then
args+=(--pipeline "$PIPELINE")
args+=(--from "$SOURCE_ORG" --to "$TARGET_ORG")
else
args+=(--all)
fi
npm run promote -- "${args[@]}"
else
npm run promote -- --all --apply
fi
- name: Commit reconciled files and UUID state
if: always()
shell: bash
env:
PROMOTION_OUTCOME: ${{ steps.promotion.outcome }}
run: |
set -euo pipefail
git add -A -- ':(glob).vapi-state.*.json'
if [[ "$PROMOTION_OUTCOME" == "success" ]]; then
git add -A -- resources
elif [[ -s tmp/promotion-applied.txt ]]; then
# A later transition failed. Stage each file exactly as it stood
# when its transition finished applying (promote-cmd stored that
# content in git's object store), so the failed transition's
# rewrites — even of the same files — are never committed.
while IFS=$'\t' read -r blob path; do
[[ -n "$path" ]] || continue
if [[ "$blob" == "-" ]]; then
git rm -q --cached --ignore-unmatch -- ":(literal)$path"
else
git update-index --add --cacheinfo "100644,$blob,$path"
fi
done < tmp/promotion-applied.txt
fi
if git diff --cached --quiet; then
echo "Promotion produced no Git changes."
exit 0
fi
git config user.name "vapi-gitops[bot]"
git config user.email "vapi-gitops[bot]@users.noreply.github.com"
git commit -m "chore: record promoted Vapi state [skip promotion]"
# Unstaged rewrites from a failed transition would make the rebase
# refuse to run, and then nothing would be pushed, state included.
git reset --hard HEAD
git clean -fd -- resources
for attempt in 1 2 3; do
git pull --rebase origin main
if git push; then
exit 0
fi
echo "main advanced during promotion; retrying ($attempt/3)."
done
exit 1