Skip to content

Commit b3cca78

Browse files
committed
Split workflows into ci-pr + ci-main, update moxygen workflow ref
Split verify.yml into ci-pr.yml (PR only) and ci-main.yml (main push only) to eliminate skipped job clutter. Fold publish.yml and notify-main-failure.yml into ci-main with aggregate notifications. Update setup-deps-tarball.sh to reference omoq-ci-main.yml (renamed from omoq-publish-artifacts.yml in moxygen).
1 parent 4969f8c commit b3cca78

5 files changed

Lines changed: 307 additions & 239 deletions

File tree

.github/workflows/ci-main.yml

Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
name: ci main
2+
3+
# Full pipeline on push to main: format, build/test, publish artifacts + Docker,
4+
# release snapshot, notify. PRs use ci-pr.yml (format + build/test only).
5+
#
6+
# Job graph:
7+
#
8+
# format ─────────────────────────────────────────────┐
9+
# build (linux, asan debug) ── publish ── release ────┼── notify
10+
# │ (always)
11+
12+
on:
13+
push:
14+
branches: [main]
15+
16+
concurrency:
17+
group: ${{ github.workflow }}-${{ github.ref }}
18+
cancel-in-progress: false
19+
20+
permissions:
21+
contents: write
22+
checks: write
23+
packages: write
24+
25+
jobs:
26+
# ════════════════════════════════════════════════════════════════════════════
27+
# Verify: format + build/test matrix
28+
# ════════════════════════════════════════════════════════════════════════════
29+
30+
format:
31+
runs-on: ubuntu-latest
32+
container: debian:trixie
33+
steps:
34+
- name: Install tools
35+
run: apt-get update && apt-get install -y --no-install-recommends ca-certificates git clang-format
36+
37+
- uses: actions/checkout@v4
38+
39+
- name: Check formatting
40+
run: bash scripts/format.sh --check
41+
42+
build:
43+
strategy:
44+
fail-fast: false
45+
matrix:
46+
include:
47+
- name: linux
48+
preset: default
49+
build_dir: build
50+
runner: ubuntu-22.04
51+
- name: asan debug
52+
preset: san
53+
build_dir: build-san
54+
runner: ubuntu-22.04
55+
name: ${{ matrix.name }}
56+
runs-on: ${{ matrix.runner }}
57+
steps:
58+
- name: Generate app token
59+
id: app-token
60+
uses: actions/create-github-app-token@v2
61+
with:
62+
app-id: ${{ secrets.OMOQ_APP_ID }}
63+
private-key: ${{ secrets.OMOQ_APP_PRIV_KEY }}
64+
65+
- uses: actions/checkout@v4
66+
with:
67+
submodules: true
68+
69+
- name: Install system dependencies
70+
run: bash deps/moxygen/standalone/install-system-deps.sh
71+
72+
- name: Download moxygen artifacts
73+
env:
74+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
75+
run: bash scripts/setup-deps-tarball.sh
76+
77+
- name: Configure
78+
run: bash scripts/configure.sh ${{ matrix.build_dir }} ${{ matrix.preset }}
79+
80+
- name: Build
81+
run: cmake --build ${{ matrix.build_dir }} -j$(getconf _NPROCESSORS_ONLN)
82+
83+
- name: Test
84+
env:
85+
ASAN_OPTIONS: ${{ matrix.name == 'asan debug' && 'detect_leaks=1:abort_on_error=1' || '' }}
86+
run: ctest --test-dir ${{ matrix.build_dir }} --output-on-failure --output-junit test-results.xml
87+
88+
- name: Publish test results
89+
uses: dorny/test-reporter@v1.9.1
90+
if: success() || failure()
91+
with:
92+
name: "test (${{ matrix.name }})"
93+
path: ${{ matrix.build_dir }}/test-results.xml
94+
reporter: java-junit
95+
fail-on-empty: ${{ job.status == 'success' && 'true' || 'false' }}
96+
97+
# ════════════════════════════════════════════════════════════════════════════
98+
# Publish: build o-rly artifacts + Docker image (needs verify to pass)
99+
# ════════════════════════════════════════════════════════════════════════════
100+
101+
publish:
102+
needs: [build]
103+
strategy:
104+
fail-fast: false
105+
matrix:
106+
include:
107+
- name: ubuntu-22.04-amd64
108+
name: publish (${{ matrix.name }})
109+
runs-on: ubuntu-22.04
110+
steps:
111+
- name: Generate app token
112+
id: app-token
113+
uses: actions/create-github-app-token@v2
114+
with:
115+
app-id: ${{ secrets.OMOQ_APP_ID }}
116+
private-key: ${{ secrets.OMOQ_APP_PRIV_KEY }}
117+
118+
- uses: actions/checkout@v4
119+
with:
120+
submodules: true
121+
122+
- name: Install system dependencies
123+
run: bash deps/moxygen/standalone/install-system-deps.sh
124+
125+
- name: Download moxygen artifacts
126+
env:
127+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
128+
run: bash scripts/setup-deps-tarball.sh
129+
130+
- name: Set up ccache
131+
uses: hendrikmuhs/ccache-action@v1
132+
with:
133+
key: publish-${{ matrix.name }}
134+
max-size: 500M
135+
136+
- name: Configure
137+
run: |
138+
cmake -S . -B _build --preset default \
139+
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
140+
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
141+
-DCMAKE_PREFIX_PATH="$(cat .scratch/cmake_prefix_path.txt)" \
142+
-DBUILD_TESTING=OFF
143+
144+
- name: Build
145+
run: cmake --build _build -j$(getconf _NPROCESSORS_ONLN)
146+
147+
- name: Install
148+
run: cmake --install _build --prefix "$GITHUB_WORKSPACE/install"
149+
150+
- name: Log in to GHCR
151+
if: runner.os == 'Linux'
152+
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
153+
154+
- name: Build and push Docker image
155+
if: runner.os == 'Linux'
156+
run: |
157+
SHORT="${GITHUB_SHA:0:7}"
158+
IMAGE="ghcr.io/${{ github.repository }}"
159+
docker build -f docker/Dockerfile \
160+
-t "${IMAGE}:${SHORT}" \
161+
-t "${IMAGE}:latest" \
162+
.
163+
docker push "${IMAGE}:${SHORT}"
164+
docker push "${IMAGE}:latest"
165+
166+
- name: Package
167+
id: package
168+
run: |
169+
ARTIFACT="${{ github.event.repository.name }}-${{ matrix.name }}.tar.gz"
170+
tar czf "$ARTIFACT" -C "$GITHUB_WORKSPACE/install" .
171+
echo "artifact=$ARTIFACT" >> "$GITHUB_OUTPUT"
172+
173+
- name: Upload artifact
174+
uses: actions/upload-artifact@v4
175+
with:
176+
name: ${{ steps.package.outputs.artifact }}
177+
path: ${{ steps.package.outputs.artifact }}
178+
retention-days: 90
179+
180+
# ════════════════════════════════════════════════════════════════════════════
181+
# Release: create/update snapshot-latest pre-release (all green)
182+
# ════════════════════════════════════════════════════════════════════════════
183+
184+
release:
185+
needs: [build, publish]
186+
runs-on: ubuntu-22.04
187+
steps:
188+
- uses: actions/checkout@v4
189+
190+
- name: Download all artifacts
191+
uses: actions/download-artifact@v4
192+
with:
193+
path: artifacts/
194+
195+
- name: Publish snapshot
196+
env:
197+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
198+
run: |
199+
SHORT="${GITHUB_SHA:0:7}"
200+
TAG="snapshot-latest"
201+
202+
gh release delete "$TAG" --yes 2>/dev/null || true
203+
git tag -d "$TAG" 2>/dev/null || true
204+
git push origin ":refs/tags/$TAG" 2>/dev/null || true
205+
206+
gh release create "$TAG" artifacts/**/* \
207+
--title "Latest build ($SHORT)" \
208+
--prerelease \
209+
--notes "$(cat <<EOF
210+
Rolling snapshot of the latest build from \`main\`.
211+
212+
**Commit:** \`${GITHUB_SHA}\`
213+
**Built:** $(date -u +%Y-%m-%dT%H:%M:%SZ)
214+
**Docker:** \`ghcr.io/${{ github.repository }}:${SHORT}\`
215+
216+
This pre-release is automatically replaced on every push to \`main\`.
217+
EOF
218+
)"
219+
220+
# ════════════════════════════════════════════════════════════════════════════
221+
# Notify: aggregate status (runs after everything)
222+
# ════════════════════════════════════════════════════════════════════════════
223+
224+
notify:
225+
needs: [format, build, publish, release]
226+
if: always()
227+
runs-on: ubuntu-22.04
228+
steps:
229+
- name: Notify Slack
230+
continue-on-error: true
231+
env:
232+
SLACK_WEBHOOK_URL: ${{ secrets.OMOQ_SLACK_WEBHOOK_URL }}
233+
run: |
234+
SHORT="${GITHUB_SHA:0:7}"
235+
RUN_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
236+
237+
# Map job results to status symbols
238+
fmt_status() {
239+
case "$1" in
240+
success) echo "✓" ;;
241+
failure) echo "✗" ;;
242+
cancelled) echo "⊘" ;;
243+
*) echo "—" ;;
244+
esac
245+
}
246+
247+
FMT=$(fmt_status "${{ needs.format.result }}")
248+
VER=$(fmt_status "${{ needs.build.result }}")
249+
PUB=$(fmt_status "${{ needs.publish.result }}")
250+
REL=$(fmt_status "${{ needs.release.result }}")
251+
252+
STATUS="format:${FMT} verify:${VER} publish:${PUB} release:${REL}"
253+
254+
if [ "${{ needs.release.result }}" = "success" ]; then
255+
REL_URL="${{ github.server_url }}/${{ github.repository }}/releases/tag/snapshot-latest"
256+
TEXT=":white_check_mark: *${{ github.repository }}* \`${{ github.ref_name }}\` \`${SHORT}\` — ${STATUS} <${RUN_URL}|#${{ github.run_number }}> artifacts: <${REL_URL}|view>"
257+
else
258+
TEXT=":x: *${{ github.repository }}* \`${{ github.ref_name }}\` \`${SHORT}\` — ${STATUS} <${RUN_URL}|#${{ github.run_number }}>"
259+
fi
260+
261+
curl -s -X POST "$SLACK_WEBHOOK_URL" \
262+
-H "Content-Type: application/json" \
263+
--data "{\"text\": \"${TEXT}\"}"
264+
265+
- name: Notify email
266+
continue-on-error: true
267+
env:
268+
AWS_ACCESS_KEY_ID: ${{ secrets.OMOQ_AWS_ACCESS_KEY_ID }}
269+
AWS_SECRET_ACCESS_KEY: ${{ secrets.OMOQ_AWS_SECRET_ACCESS_KEY }}
270+
AWS_DEFAULT_REGION: us-east-1
271+
run: |
272+
SHORT="${GITHUB_SHA:0:7}"
273+
RUN_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
274+
275+
FMT="${{ needs.format.result }}"
276+
VER="${{ needs.build.result }}"
277+
PUB="${{ needs.publish.result }}"
278+
REL="${{ needs.release.result }}"
279+
280+
STATUS="format:${FMT} verify:${VER} publish:${PUB} release:${REL}"
281+
282+
if [ "${{ needs.release.result }}" = "success" ]; then
283+
REL_URL="${{ github.server_url }}/${{ github.repository }}/releases/tag/snapshot-latest"
284+
SUBJECT="[o-rly] published ${{ github.ref_name }} ${SHORT}"
285+
BODY="Repository: ${{ github.repository }}\nBranch: ${{ github.ref_name }}\nCommit: ${GITHUB_SHA}\nStatus: ${STATUS}\nDocker: ghcr.io/${{ github.repository }}:${SHORT}\nArtifacts: ${REL_URL}\nRun: ${RUN_URL}"
286+
else
287+
SUBJECT="[o-rly] pipeline failed ${{ github.ref_name }} ${SHORT}"
288+
BODY="Repository: ${{ github.repository }}\nBranch: ${{ github.ref_name }}\nCommit: ${GITHUB_SHA}\nStatus: ${STATUS}\nRun: ${RUN_URL}"
289+
fi
290+
291+
aws ses send-email \
292+
--from "noreply@ci.openmoq.org" \
293+
--destination '{"ToAddresses":["github-notifications@openmoq.org"]}' \
294+
--message "{
295+
\"Subject\": {\"Data\": \"${SUBJECT}\"},
296+
\"Body\": {\"Text\": {\"Data\": \"${BODY}\"}}
297+
}"
Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
name: verify
1+
name: ci pr
2+
3+
# PR verification: format + build/test matrix.
4+
# Main push uses ci-main.yml which adds publish/release/notify.
25

36
on:
47
pull_request:
58
branches: [main]
6-
push:
7-
branches: [main]
9+
10+
concurrency:
11+
group: ${{ github.workflow }}-${{ github.ref }}
12+
cancel-in-progress: true
813

914
permissions:
1015
contents: read
@@ -77,4 +82,3 @@ jobs:
7782
path: ${{ matrix.build_dir }}/test-results.xml
7883
reporter: java-junit
7984
fail-on-empty: ${{ job.status == 'success' && 'true' || 'false' }}
80-

.github/workflows/notify-main-failure.yml

Lines changed: 0 additions & 51 deletions
This file was deleted.

0 commit comments

Comments
 (0)