-
Notifications
You must be signed in to change notification settings - Fork 0
172 lines (152 loc) · 6.99 KB
/
Copy pathnightly.yml
File metadata and controls
172 lines (152 loc) · 6.99 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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
name: Nightly (heavy doc gates)
# Runs the HEAVY doc-execution gates that per-PR run-ci skips for speed:
# SNIPPET-COMPILE · SNIPPET-RUN · EXAMPLES-RUN (tier=nightly in run-ci.sh)
# via `SW_CI_TIER=nightly bash scripts/run-ci.sh`, which runs the FULL gate set
# (nightly is a superset of the per-PR tier — nothing is only-nightly-untested).
#
# Skip-if-unchanged: the heavy gates depend on three inputs — this port, the
# shared porting-sdk (mocks + gate scripts), and signalwire-python (the oracle).
# The guard fingerprints all three HEAD SHAs into a cache key. A GREEN heavy run
# saves that key; the next nightly's guard does a cache-restore probe on the same
# key — a HIT means the exact (port, porting-sdk, python) triple already passed, so
# the heavy job is skipped. A no-op nightly then costs a cache probe, not ~45 min.
# (Cache, not run-name/API parsing: a job name does not surface as the run's .name,
# so name-based state is unreliable; actions/cache is the GitHub-native state store.)
on:
schedule:
- cron: '17 7 * * *' # 07:17 UTC daily (off the hour to avoid the cron stampede)
workflow_dispatch:
inputs:
force:
description: 'Run even if nothing changed since the last successful nightly'
type: boolean
default: false
concurrency:
group: nightly-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: read
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
jobs:
guard:
runs-on: ubuntu-latest
outputs:
changed: ${{ steps.check.outputs.changed }}
cache_key: ${{ steps.fp.outputs.cache_key }}
steps:
- name: Fingerprint the three input HEAD SHAs (port + porting-sdk + python)
id: fp
env:
GH_TOKEN: ${{ github.token }}
PSDK_TOKEN: ${{ secrets.PORTING_SDK_TOKEN }}
run: |
set -euo pipefail
port_sha='${{ github.sha }}'
# porting-sdk is private → authenticated ref lookup; python is public.
psdk_sha=$(GH_TOKEN="$PSDK_TOKEN" gh api repos/signalwire/porting-sdk/commits/main --jq .sha)
py_sha=$(gh api repos/signalwire/signalwire-python/commits/main --jq .sha)
echo "cache_key=nightly-green-v1-${port_sha}-${psdk_sha}-${py_sha}" >> "$GITHUB_OUTPUT"
echo "inputs → port=$port_sha psdk=$psdk_sha python=$py_sha"
# Probe (restore-only, no save) the green-marker cache for this exact input
# triple. A HIT means these three SHAs already passed the heavy gates.
- name: Probe last-green marker
id: probe
uses: actions/cache/restore@v6
with:
path: .nightly-green-marker
key: ${{ steps.fp.outputs.cache_key }}
lookup-only: true
- name: Decide
id: check
env:
FORCE: ${{ github.event.inputs.force }}
run: |
set -euo pipefail
if [ "$FORCE" = "true" ]; then
echo "force=true → running"; echo "changed=true" >> "$GITHUB_OUTPUT"; exit 0
fi
if [ "${{ steps.probe.outputs.cache-hit }}" = "true" ]; then
echo "this (port, porting-sdk, python) triple already passed a nightly → skipping heavy gates"
echo "changed=false" >> "$GITHUB_OUTPUT"
else
echo "input triple has not passed a nightly yet → running heavy gates"
echo "changed=true" >> "$GITHUB_OUTPUT"
fi
heavy:
needs: guard
if: needs.guard.outputs.changed == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout signalwire-typescript
uses: actions/checkout@v7
with:
path: signalwire-typescript
- name: Checkout porting-sdk (mock servers + audit scripts + EMISSION corpus)
uses: actions/checkout@v7
with:
repository: signalwire/porting-sdk
# Coordinated-pass pin: 'main' normally; set the PORTING_SDK_REF repo variable
# to a wave branch to test a coordinated porting-sdk change, declared on the PR
# (see porting-sdk/COORDINATED_PASS.md). No revert commit.
ref: ${{ vars.PORTING_SDK_REF || 'main' }}
path: porting-sdk
token: ${{ secrets.PORTING_SDK_TOKEN }}
- name: Checkout signalwire-python (EMISSION oracle)
uses: actions/checkout@v7
with:
repository: signalwire/signalwire-python
path: signalwire-python
ref: ${{ vars.PORTING_SDK_REF || 'main' }}
- uses: actions/setup-node@v7
with:
node-version: '24'
cache: 'npm'
cache-dependency-path: signalwire-typescript/package-lock.json
- uses: actions/setup-python@v6
with:
python-version: '3.14'
- name: Install Python test harnesses (mock_relay + mock_signalwire)
run: |
python -m pip install --upgrade pip
pip install -e porting-sdk/test_harness/mock_relay \
-e porting-sdk/test_harness/mock_signalwire \
pytest pytest-timeout requests websockets
- name: Install signalwire-python (EMISSION oracle) if not importable
run: pip install -e signalwire-python || true
# SWAIG-HTTP-INVOKE differ drives the python reference through
# starlette.testclient.TestClient, which needs an httpx backend (newest
# starlette: httpx2; older: httpx). Install both so the import resolves.
- name: Install starlette TestClient HTTP backend (SWAIG-HTTP differ)
run: pip install httpx httpx2 || pip install httpx
# ACTIONLINT gate (porting-sdk actionlint_gate.py) needs the actionlint
# binary and fails LOUD when it is absent, so install it before run-ci.
- name: Install actionlint (ACTIONLINT gate)
run: |
bash <(curl -sSfL https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
sudo mv ./actionlint /usr/local/bin/actionlint
actionlint --version
- name: npm ci
working-directory: signalwire-typescript
run: npm ci
- name: Run FULL gate set incl. heavy doc gates (SW_CI_TIER=nightly)
working-directory: signalwire-typescript
env:
PORTING_SDK: ${{ github.workspace }}/porting-sdk
SW_CI_TIER: nightly
# COORDINATED-PASS reads the live PR body/labels via 'gh api' to see a
# 'Coordinated-With:' declaration edited after the triggering push.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bash scripts/run-ci.sh
# Save the green marker ONLY on success (this step runs only if run-ci passed),
# so the next nightly skips this exact input triple. A failed heavy run saves
# nothing → it re-runs next nightly until it goes green.
- name: Record green marker for this input triple
run: 'echo "$GITHUB_SHA green $(date -u +%FT%TZ)" > .nightly-green-marker'
working-directory: ${{ github.workspace }}
- uses: actions/cache/save@v6
with:
path: .nightly-green-marker
key: ${{ needs.guard.outputs.cache_key }}