Skip to content

Commit 7f80896

Browse files
committed
CI optimizations
- Skip CI for draft PRs and redundant master-push re-runs; membrowse nightly. - Add smoke test (8 configs, CFLAGS=-Werror, post-merge tree, fail-fast on conflicts). - Add wait-for-smoke composite action for downstream CI gating. - Add check-source-text + bash -n + shellcheck workflow (script in make dist). - Cache apt-get update in install-apt-deps composite on cache hit.
1 parent dc56e87 commit 7f80896

89 files changed

Lines changed: 942 additions & 244 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/actions/install-apt-deps/action.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ runs:
5454
5555
- name: Install packages
5656
shell: bash
57+
env:
58+
APT_CACHE_HIT: ${{ steps.apt-cache.outputs.cache-hit }}
5759
run: |
5860
export DEBIAN_FRONTEND=noninteractive
5961
RETRIES=${{ inputs.retries }}
@@ -62,6 +64,18 @@ runs:
6264
if [ "${{ inputs.no-install-recommends }}" = "true" ]; then
6365
NO_REC="--no-install-recommends"
6466
fi
67+
68+
# Fast path: on cache hit the .debs are already pre-seeded into
69+
# /var/cache/apt/archives. Try installing directly first; if that
70+
# fails (e.g. the cached .debs were superseded in the index) fall
71+
# through to the regular update + install path.
72+
if [ "$APT_CACHE_HIT" = "true" ]; then
73+
if sudo apt-get install -y $NO_REC ${{ inputs.packages }}; then
74+
exit 0
75+
fi
76+
echo "::warning::install from cached .debs failed, falling back to apt-get update"
77+
fi
78+
6579
for i in $(seq 1 $RETRIES); do
6680
if sudo apt-get update -q && \
6781
sudo apt-get install -y $NO_REC ${{ inputs.packages }}; then
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
name: 'Wait for Smoke Test'
2+
description: 'Polls the Smoke Test workflow for the current commit and fails if it failed.'
3+
4+
# Designed to be the leading job in pull_request-triggered workflows so that
5+
# expensive integration CI does not run unless the smoke build passes.
6+
#
7+
# Push events bypass the wait entirely (we still get smoke results for those
8+
# pushes, but other CI is not gated on push). For drafts, callers should
9+
# skip dependent jobs via `if: github.event.pull_request.draft == false` -
10+
# this action will still pass through if smoke is skipped or absent.
11+
12+
inputs:
13+
workflow:
14+
description: 'Name of the smoke workflow file to wait on'
15+
required: false
16+
default: 'smoke-test.yml'
17+
timeout-seconds:
18+
description: 'Maximum time to wait for smoke to complete'
19+
required: false
20+
default: '1800'
21+
poll-seconds:
22+
description: 'Polling interval'
23+
required: false
24+
default: '20'
25+
github-token:
26+
description: 'GITHUB_TOKEN with actions:read permission'
27+
required: true
28+
29+
runs:
30+
using: 'composite'
31+
steps:
32+
- name: Wait for smoke
33+
shell: bash
34+
env:
35+
GH_TOKEN: ${{ inputs.github-token }}
36+
SMOKE_WORKFLOW: ${{ inputs.workflow }}
37+
TIMEOUT: ${{ inputs.timeout-seconds }}
38+
POLL: ${{ inputs.poll-seconds }}
39+
REPO: ${{ github.repository }}
40+
run: |
41+
set -u
42+
# Only gate pull_request events. Push events are not gated.
43+
if [ "${{ github.event_name }}" != "pull_request" ]; then
44+
echo "Not a pull_request event - skipping smoke gate."
45+
exit 0
46+
fi
47+
48+
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
49+
echo "Waiting for $SMOKE_WORKFLOW on $HEAD_SHA (timeout ${TIMEOUT}s)"
50+
51+
START=$(date +%s)
52+
while :; do
53+
NOW=$(date +%s)
54+
ELAPSED=$((NOW - START))
55+
if [ "$ELAPSED" -ge "$TIMEOUT" ]; then
56+
echo "::error::Timed out after ${TIMEOUT}s waiting for $SMOKE_WORKFLOW on $HEAD_SHA"
57+
exit 1
58+
fi
59+
60+
# Look up the latest run for this workflow + head SHA.
61+
RUN_JSON=$(gh api \
62+
"repos/${REPO}/actions/workflows/${SMOKE_WORKFLOW}/runs?head_sha=${HEAD_SHA}&per_page=1" \
63+
2>/dev/null || echo '{}')
64+
65+
STATUS=$(echo "$RUN_JSON" | jq -r '.workflow_runs[0].status // "missing"')
66+
CONCLUSION=$(echo "$RUN_JSON" | jq -r '.workflow_runs[0].conclusion // ""')
67+
RUN_URL=$(echo "$RUN_JSON" | jq -r '.workflow_runs[0].html_url // ""')
68+
69+
case "$STATUS" in
70+
completed)
71+
case "$CONCLUSION" in
72+
success)
73+
echo "Smoke test passed: $RUN_URL"
74+
exit 0
75+
;;
76+
skipped|neutral)
77+
echo "Smoke test was $CONCLUSION - treating as pass: $RUN_URL"
78+
exit 0
79+
;;
80+
*)
81+
echo "::error::Smoke test concluded as '$CONCLUSION': $RUN_URL"
82+
exit 1
83+
;;
84+
esac
85+
;;
86+
missing)
87+
echo "[$ELAPSED s] No smoke run yet for $HEAD_SHA"
88+
;;
89+
*)
90+
echo "[$ELAPSED s] Smoke status=$STATUS ($RUN_URL)"
91+
;;
92+
esac
93+
94+
sleep "$POLL"
95+
done

0 commit comments

Comments
 (0)