-
Notifications
You must be signed in to change notification settings - Fork 4
165 lines (147 loc) · 5.89 KB
/
Copy pathc-cpp.yml
File metadata and controls
165 lines (147 loc) · 5.89 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
name: C/C++ CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
contents: write # required to push tags & create releases
jobs:
# GTest/CMake unit suite (test/server_test.cpp). Previously never run in CI.
gtest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install GTest + CMake
run: sudo apt-get update && sudo apt-get install -y cmake libgtest-dev
- name: Build and run unit tests
run: |
mkdir build && cd build
cmake ..
make
ctest --output-on-failure
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false # one architecture failing must not block the others
matrix:
include:
# Native target: built with the default toolchain AND functionally tested (the
# binary runs on the x86_64 runner, so it gets the full -t suite + monitor.sh).
- arch: x86_64
cc: gcc
strip: strip
native: true
# Cross targets: compiled with a Linux cross-toolchain and ELF-arch-verified only
# (they cannot execute on the x86_64 runner). The native job is the functional gate.
- arch: aarch64
cc: aarch64-linux-gnu-gcc
strip: aarch64-linux-gnu-strip
pkg: gcc-aarch64-linux-gnu
machine: AArch64 # readelf -h "Machine:" value (exact, unlike file's shared "ARM")
native: false
- arch: armv7
cc: arm-linux-gnueabihf-gcc
strip: arm-linux-gnueabihf-strip
pkg: gcc-arm-linux-gnueabihf
machine: ARM # 32-bit ARM reports "ARM"; aarch64 reports "AArch64"
native: false
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # ensure full history & tags are available
- name: Install cross toolchain
if: matrix.pkg != ''
run: sudo apt-get update && sudo apt-get install -y ${{ matrix.pkg }}
- name: Clean build
run: make clean || true
- name: Build (Release)
run: make BUILD_TYPE=release CC=${{ matrix.cc }} STRIP=${{ matrix.strip }}
- name: Run unit tests (native only)
if: matrix.native
run: |
echo "Running unit tests..."
# 'all' runs every automated unit test and returns non-zero on any failure,
# so a broken assertion now fails the build (previously -t always exited 0).
./processWatchdog -t all
- name: Verify cross binary architecture
if: ${{ !matrix.native }}
run: |
test -f processWatchdog || { echo "ERROR: build produced no binary"; exit 1; }
MACHINE=$(readelf -h processWatchdog | sed -n 's/.*Machine:[[:space:]]*//p')
echo "ELF machine: $MACHINE"
# Exact match on the ELF machine type: AArch64 and ARM are distinct, so an armv7
# target cannot false-pass on an accidental aarch64 build (or vice-versa).
[ "$MACHINE" = "${{ matrix.machine }}" ] || {
echo "ERROR: expected ${{ matrix.machine }} for ${{ matrix.arch }}, got '$MACHINE'"
exit 1
}
- name: Run watchdog (native only)
if: matrix.native
run: |
echo "Running processWatchdog..."
chmod +x monitor.sh
./monitor.sh 2 1 5 3 600 ./processWatchdog > release_watchdog_stdout.log 2> release_watchdog_stderr.log
echo "Standard Output:"
cat release_watchdog_stdout.log
echo "Standard Error:"
cat release_watchdog_stderr.log
- name: Name binary per architecture
run: mv processWatchdog processWatchdog-linux-${{ matrix.arch }}
- name: Upload binary artifact
uses: actions/upload-artifact@v4
with:
name: processWatchdog-linux-${{ matrix.arch }}
path: processWatchdog-linux-${{ matrix.arch }}
if-no-files-found: error
# --- Release automation: runs once after all architectures build, only on push to main ---
release:
needs: build
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download all binaries
uses: actions/download-artifact@v4
with:
pattern: processWatchdog-linux-*
path: dist
merge-multiple: true # flatten all artifacts into dist/
- name: Extract version from main.c
id: get_version
run: |
VERSION=$(grep '#define VERSION' src/main.c | sed -E 's/.*"([^"]+)".*/\1/')
if [ -z "$VERSION" ]; then
echo "Failed to extract VERSION from main.c"; exit 1
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Detected version: $VERSION"
- name: Check if tag exists remotely
id: check_tag
run: |
git fetch --tags --force
TAG="v${{ steps.get_version.outputs.version }}"
if git ls-remote --tags origin "refs/tags/${TAG}" | grep -q "${TAG}$"; then
echo "exists=true" >> "$GITHUB_OUTPUT"
echo "Tag ${TAG} already exists."
else
echo "exists=false" >> "$GITHUB_OUTPUT"
echo "Tag ${TAG} does not exist."
fi
- name: Create tag
if: steps.check_tag.outputs.exists == 'false'
run: |
git config user.name "diffstorm"
git config user.email "diffstorm@gmail.com"
TAG="v${{ steps.get_version.outputs.version }}"
git tag "${TAG}"
git push origin "${TAG}"
- name: Create GitHub Release
if: steps.check_tag.outputs.exists == 'false'
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.get_version.outputs.version }}
generate_release_notes: true
files: dist/processWatchdog-linux-* # attach all Linux arch binaries