Skip to content

Commit 1b62554

Browse files
committed
Add GitHub Actions workflow for build and test process
1 parent 2a5c056 commit 1b62554

1 file changed

Lines changed: 247 additions & 0 deletions

File tree

.github/workflows/build.yml

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
name: Build and Test
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main, develop ]
8+
workflow_dispatch:
9+
10+
env:
11+
IMAGE_NAME: handbuilt-linux
12+
REGISTRY: ghcr.io
13+
14+
jobs:
15+
# ===========================================================================
16+
# Build Job
17+
# ===========================================================================
18+
build:
19+
name: Build Distribution
20+
runs-on: ubuntu-latest
21+
permissions:
22+
contents: read
23+
packages: write
24+
25+
steps:
26+
- name: Checkout code
27+
uses: actions/checkout@v4
28+
29+
- name: Set up Docker Buildx
30+
uses: docker/setup-buildx-action@v3
31+
32+
- name: Log in to Container Registry
33+
if: github.event_name != 'pull_request'
34+
uses: docker/login-action@v3
35+
with:
36+
registry: ${{ env.REGISTRY }}
37+
username: ${{ github.actor }}
38+
password: ${{ secrets.GITHUB_TOKEN }}
39+
40+
- name: Extract metadata
41+
id: meta
42+
uses: docker/metadata-action@v5
43+
with:
44+
images: ${{ env.REGISTRY }}/${{ github.repository }}
45+
tags: |
46+
type=ref,event=branch
47+
type=ref,event=pr
48+
type=semver,pattern={{version}}
49+
type=semver,pattern={{major}}.{{minor}}
50+
type=sha,prefix={{branch}}-
51+
type=raw,value=latest,enable={{is_default_branch}}
52+
53+
- name: Build Docker image
54+
uses: docker/build-push-action@v5
55+
with:
56+
context: .
57+
push: false
58+
load: true
59+
tags: ${{ env.IMAGE_NAME }}:test
60+
cache-from: type=gha
61+
cache-to: type=gha,mode=max
62+
build-args: |
63+
BUILD_JOBS=auto
64+
65+
- name: Test Docker image
66+
run: |
67+
docker run --rm ${{ env.IMAGE_NAME }}:test test -f /distro/output.iso
68+
docker run --rm ${{ env.IMAGE_NAME }}:test test -f /distro/bzImage
69+
docker run --rm ${{ env.IMAGE_NAME }}:test test -f /distro/initramfs
70+
71+
- name: Extract artifacts
72+
run: |
73+
mkdir -p artifacts
74+
docker run --rm ${{ env.IMAGE_NAME }}:test cat /distro/output.iso > artifacts/output.iso
75+
docker run --rm ${{ env.IMAGE_NAME }}:test cat /distro/bzImage > artifacts/bzImage
76+
docker run --rm ${{ env.IMAGE_NAME }}:test cat /distro/initramfs > artifacts/initramfs
77+
78+
- name: Upload artifacts
79+
uses: actions/upload-artifact@v4
80+
with:
81+
name: linux-distribution
82+
path: artifacts/
83+
retention-days: 30
84+
85+
- name: Build and push Docker image
86+
if: github.event_name != 'pull_request'
87+
uses: docker/build-push-action@v5
88+
with:
89+
context: .
90+
push: true
91+
tags: ${{ steps.meta.outputs.tags }}
92+
labels: ${{ steps.meta.outputs.labels }}
93+
cache-from: type=gha
94+
cache-to: type=gha,mode=max
95+
96+
# ===========================================================================
97+
# Test Job
98+
# ===========================================================================
99+
test:
100+
name: Run Tests
101+
runs-on: ubuntu-latest
102+
needs: build
103+
104+
steps:
105+
- name: Checkout code
106+
uses: actions/checkout@v4
107+
108+
- name: Set up Docker Buildx
109+
uses: docker/setup-buildx-action@v3
110+
111+
- name: Build Docker image for testing
112+
uses: docker/build-push-action@v5
113+
with:
114+
context: .
115+
load: true
116+
tags: ${{ env.IMAGE_NAME }}:test
117+
cache-from: type=gha
118+
119+
- name: Download artifacts
120+
uses: actions/download-artifact@v4
121+
with:
122+
name: linux-distribution
123+
path: ./artifacts
124+
125+
- name: Run test suite
126+
run: |
127+
chmod +x scripts/*.sh
128+
docker tag ${{ env.IMAGE_NAME }}:test handbuilt-linux:latest
129+
./scripts/test.sh
130+
131+
- name: Validate ISO
132+
run: |
133+
file artifacts/output.iso | grep -q "ISO 9660"
134+
135+
- name: Validate initramfs
136+
run: |
137+
file artifacts/initramfs | grep -q "gzip compressed"
138+
139+
- name: Check script syntax
140+
run: |
141+
bash -n build.sh
142+
sh -n init.sh
143+
144+
# ===========================================================================
145+
# Lint Job
146+
# ===========================================================================
147+
lint:
148+
name: Lint and Code Quality
149+
runs-on: ubuntu-latest
150+
151+
steps:
152+
- name: Checkout code
153+
uses: actions/checkout@v4
154+
155+
- name: Run hadolint (Dockerfile linter)
156+
uses: hadolint/hadolint-action@v3.1.0
157+
with:
158+
dockerfile: Dockerfile
159+
ignore: DL3008
160+
161+
- name: Run shellcheck
162+
uses: ludeeus/action-shellcheck@master
163+
with:
164+
scandir: './scripts'
165+
format: gcc
166+
severity: warning
167+
168+
- name: Check shell scripts
169+
run: |
170+
bash -n build.sh
171+
sh -n init.sh
172+
for script in scripts/*.sh; do
173+
bash -n "$script"
174+
done
175+
176+
# ===========================================================================
177+
# Security Scan Job
178+
# ===========================================================================
179+
security:
180+
name: Security Scan
181+
runs-on: ubuntu-latest
182+
needs: build
183+
permissions:
184+
security-events: write
185+
186+
steps:
187+
- name: Checkout code
188+
uses: actions/checkout@v4
189+
190+
- name: Build Docker image
191+
uses: docker/build-push-action@v5
192+
with:
193+
context: .
194+
load: true
195+
tags: ${{ env.IMAGE_NAME }}:scan
196+
cache-from: type=gha
197+
198+
- name: Run Trivy vulnerability scanner
199+
uses: aquasecurity/trivy-action@master
200+
with:
201+
image-ref: ${{ env.IMAGE_NAME }}:scan
202+
format: 'sarif'
203+
output: 'trivy-results.sarif'
204+
205+
- name: Upload Trivy results to GitHub Security
206+
uses: github/codeql-action/upload-sarif@v3
207+
if: always()
208+
with:
209+
sarif_file: 'trivy-results.sarif'
210+
211+
# ===========================================================================
212+
# Release Job (only on tags)
213+
# ===========================================================================
214+
release:
215+
name: Create Release
216+
runs-on: ubuntu-latest
217+
needs: [build, test, lint]
218+
if: startsWith(github.ref, 'refs/tags/v')
219+
permissions:
220+
contents: write
221+
222+
steps:
223+
- name: Checkout code
224+
uses: actions/checkout@v4
225+
226+
- name: Download artifacts
227+
uses: actions/download-artifact@v4
228+
with:
229+
name: linux-distribution
230+
path: ./artifacts
231+
232+
- name: Create checksums
233+
run: |
234+
cd artifacts
235+
sha256sum * > checksums.txt
236+
237+
- name: Create Release
238+
uses: softprops/action-gh-release@v1
239+
with:
240+
files: |
241+
artifacts/output.iso
242+
artifacts/bzImage
243+
artifacts/initramfs
244+
artifacts/checksums.txt
245+
generate_release_notes: true
246+
env:
247+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)