Skip to content

Commit ef802c2

Browse files
author
Mohamed Chorfa
committed
ci: add GitHub Actions workflows for CI, release, and supply chain security
Add comprehensive CI/CD pipeline with security-first approach: - CI workflow: build, test, lint, clippy, security audit, integration and E2E tests - Release workflow: container build/push with SLSA provenance, SBOM generation and signing via Sigstore/cosign, GitHub release creation - SLSA provenance workflow: SLSA Level 3+ attestation generation using slsa-github-generator - Dependency ingestion workflow: weekly schedule Signed-off-by: Mohamed Chorfa <mohamed.chorfa@thalesgroup.com>
1 parent 8b33377 commit ef802c2

160 files changed

Lines changed: 29430 additions & 174 deletions

File tree

Some content is hidden

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

.github/workflows/ci.yaml

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# TEA Server CI Pipeline
2+
#
3+
# Runs on all PRs and pushes to main. Validates:
4+
# - Build (cargo check)
5+
# - Tests (cargo test)
6+
# - Linting (cargo clippy)
7+
# - Security audit (cargo audit)
8+
9+
name: CI
10+
11+
on:
12+
push:
13+
branches: [main]
14+
paths:
15+
- 'tea-server/**'
16+
- 'proto/**'
17+
- '.github/workflows/ci.yaml'
18+
pull_request:
19+
branches: [main]
20+
paths:
21+
- 'tea-server/**'
22+
- 'proto/**'
23+
- '.github/workflows/ci.yaml'
24+
25+
permissions:
26+
contents: read
27+
28+
env:
29+
CARGO_TERM_COLOR: always
30+
RUST_BACKTRACE: 1
31+
32+
jobs:
33+
# ─────────────────────────────────────────────────────────────────────────────
34+
# Build and Test
35+
# ─────────────────────────────────────────────────────────────────────────────
36+
build:
37+
name: Build & Test
38+
runs-on: ubuntu-latest
39+
defaults:
40+
run:
41+
working-directory: tea-server
42+
43+
steps:
44+
- name: Checkout
45+
uses: actions/checkout@v4
46+
47+
- name: Install Rust toolchain
48+
uses: dtolnay/rust-toolchain@stable
49+
with:
50+
components: clippy, rustfmt
51+
52+
- name: Cache cargo artifacts
53+
uses: Swatinem/rust-cache@v2
54+
with:
55+
workspaces: tea-server -> target
56+
key: ${{ runner.os }}-rust-${{ hashFiles('tea-server/Cargo.lock') }}
57+
58+
- name: Check formatting
59+
run: cargo fmt -- --check
60+
61+
- name: Build
62+
run: cargo check --locked
63+
64+
- name: Run clippy
65+
run: cargo clippy -- -D warnings
66+
67+
- name: Run tests
68+
run: cargo test --locked
69+
env:
70+
# Disable integration tests that need Docker
71+
RUST_TEST_SKIP_INTEGRATION: 1
72+
73+
# ─────────────────────────────────────────────────────────────────────────────
74+
# Security Audit
75+
# ─────────────────────────────────────────────────────────────────────────────
76+
audit:
77+
name: Security Audit
78+
runs-on: ubuntu-latest
79+
defaults:
80+
run:
81+
working-directory: tea-server
82+
83+
steps:
84+
- name: Checkout
85+
uses: actions/checkout@v4
86+
87+
- name: Install Rust toolchain
88+
uses: dtolnay/rust-toolchain@stable
89+
90+
- name: Install cargo-audit
91+
run: cargo install cargo-audit
92+
93+
- name: Run security audit
94+
run: cargo audit
95+
96+
# ─────────────────────────────────────────────────────────────────────────────
97+
# Integration Tests (with testcontainers)
98+
# ─────────────────────────────────────────────────────────────────────────────
99+
integration:
100+
name: Integration Tests
101+
runs-on: ubuntu-latest
102+
needs: build
103+
defaults:
104+
run:
105+
working-directory: tea-server
106+
107+
steps:
108+
- name: Checkout
109+
uses: actions/checkout@v4
110+
111+
- name: Install Rust toolchain
112+
uses: dtolnay/rust-toolchain@stable
113+
114+
- name: Cache cargo artifacts
115+
uses: Swatinem/rust-cache@v2
116+
with:
117+
workspaces: tea-server -> target
118+
119+
- name: Run integration tests
120+
run: cargo test --test integration
121+
# testcontainers will spin up Postgres automatically
122+
123+
# ─────────────────────────────────────────────────────────────────────────────
124+
# E2E Conformance Tests
125+
# ─────────────────────────────────────────────────────────────────────────────
126+
e2e:
127+
name: E2E Conformance Tests
128+
runs-on: ubuntu-latest
129+
needs: build
130+
defaults:
131+
run:
132+
working-directory: tea-server
133+
134+
steps:
135+
- name: Checkout
136+
uses: actions/checkout@v4
137+
138+
- name: Install Rust toolchain
139+
uses: dtolnay/rust-toolchain@stable
140+
141+
- name: Cache cargo artifacts
142+
uses: Swatinem/rust-cache@v2
143+
with:
144+
workspaces: tea-server -> target
145+
146+
- name: Run E2E conformance tests
147+
run: cargo test --test e2e_conformance

.github/workflows/ingest-deps.yaml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Ingest Dependencies
2+
3+
on:
4+
schedule:
5+
- cron: "0 0 * * 0" # Weekly on Sunday
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
packages: write # For pushing to GHCR
11+
12+
jobs:
13+
ingest:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
19+
- name: Setup Go
20+
uses: actions/setup-go@v5
21+
with:
22+
go-version: 1.22
23+
24+
- name: Install Dagger
25+
run: |
26+
curl -L https://dl.dagger.io/dagger/install.sh | sh
27+
export PATH=$PATH:$HOME/.dagger/bin
28+
29+
- name: Login to GHCR
30+
uses: docker/login-action@v3
31+
with:
32+
registry: ghcr.io
33+
username: ${{ github.actor }}
34+
password: ${{ secrets.GITHUB_TOKEN }}
35+
36+
- name: Run IngestDeps and Push Snapshot
37+
run: |
38+
# Run Dagger to ingest deps
39+
dagger call ingest-deps --source . export --path snapshot
40+
# Push the snapshot directory as OCI artifact using oras
41+
oras push ghcr.io/${{ github.repository }}/deps-snapshot:latest snapshot/ --annotation org.opencontainers.image.source=https://github.com/${{ github.repository }}

.github/workflows/release.yaml

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# TEA Server Release Pipeline
2+
#
3+
# Builds and publishes container images on tag push.
4+
# Integrates with SLSA provenance workflow for supply chain security.
5+
6+
name: Release
7+
8+
on:
9+
push:
10+
tags:
11+
- "v*"
12+
13+
permissions:
14+
contents: read
15+
packages: write
16+
id-token: write # Required for Sigstore signing
17+
18+
env:
19+
REGISTRY: ghcr.io
20+
IMAGE_NAME: ${{ github.repository }}/tea-server
21+
22+
jobs:
23+
# ─────────────────────────────────────────────────────────────────────────────
24+
# Build and push container image
25+
# ─────────────────────────────────────────────────────────────────────────────
26+
build:
27+
runs-on: ubuntu-latest
28+
outputs:
29+
digest: ${{ steps.build.outputs.digest }}
30+
version: ${{ steps.meta.outputs.version }}
31+
32+
steps:
33+
- name: Checkout
34+
uses: actions/checkout@v4
35+
36+
- name: Set up Docker Buildx
37+
uses: docker/setup-buildx-action@v3
38+
39+
- name: Log in to Container Registry
40+
uses: docker/login-action@v3
41+
with:
42+
registry: ${{ env.REGISTRY }}
43+
username: ${{ github.actor }}
44+
password: ${{ secrets.GITHUB_TOKEN }}
45+
46+
- name: Extract metadata
47+
id: meta
48+
uses: docker/metadata-action@v5
49+
with:
50+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
51+
tags: |
52+
type=semver,pattern={{version}}
53+
type=semver,pattern={{major}}.{{minor}}
54+
type=sha,prefix=sha-
55+
56+
- name: Build and push
57+
id: build
58+
uses: docker/build-push-action@v5
59+
with:
60+
context: ./tea-server
61+
push: true
62+
tags: ${{ steps.meta.outputs.tags }}
63+
labels: ${{ steps.meta.outputs.labels }}
64+
provenance: true
65+
sbom: true
66+
outputs: type=registry,oci-mediatypes=true
67+
68+
# ─────────────────────────────────────────────────────────────────────────────
69+
# Generate SLSA provenance
70+
# ─────────────────────────────────────────────────────────────────────────────
71+
provenance:
72+
needs: build
73+
permissions:
74+
contents: read
75+
packages: write
76+
id-token: write
77+
actions: read
78+
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.10.0
79+
with:
80+
image: ghcr.io/${{ github.repository }}/tea-server
81+
digest: ${{ needs.build.outputs.digest }}
82+
registry-username: ${{ github.actor }}
83+
secrets:
84+
registry-password: ${{ secrets.GITHUB_TOKEN }}
85+
86+
# ─────────────────────────────────────────────────────────────────────────────
87+
# Generate and sign SBOM
88+
# ─────────────────────────────────────────────────────────────────────────────
89+
sbom:
90+
needs: [build, provenance]
91+
runs-on: ubuntu-latest
92+
permissions:
93+
contents: read
94+
packages: write
95+
id-token: write
96+
97+
steps:
98+
- name: Checkout
99+
uses: actions/checkout@v4
100+
101+
- name: Log in to Container Registry
102+
uses: docker/login-action@v3
103+
with:
104+
registry: ${{ env.REGISTRY }}
105+
username: ${{ github.actor }}
106+
password: ${{ secrets.GITHUB_TOKEN }}
107+
108+
- name: Install cosign
109+
uses: sigstore/cosign-installer@v3
110+
111+
- name: Install Syft
112+
uses: anchore/sbom-action/download-syft@v0
113+
114+
- name: Generate SBOM
115+
run: |
116+
syft \
117+
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }} \
118+
-o spdx-json=sbom.spdx.json \
119+
-o cyclonedx-json=sbom.cdx.json
120+
121+
- name: Sign SBOM
122+
run: |
123+
cosign sign-blob \
124+
--yes \
125+
--output-signature sbom.spdx.json.sig \
126+
--output-certificate sbom.spdx.json.crt \
127+
sbom.spdx.json
128+
129+
- name: Attach SBOM to image
130+
run: |
131+
cosign attach sbom \
132+
--sbom sbom.spdx.json \
133+
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
134+
135+
- name: Upload SBOM artifacts
136+
uses: actions/upload-artifact@v4
137+
with:
138+
name: sbom
139+
path: |
140+
sbom.spdx.json
141+
sbom.cdx.json
142+
sbom.spdx.json.sig
143+
retention-days: 90
144+
145+
# ─────────────────────────────────────────────────────────────────────────────
146+
# Create GitHub Release
147+
# ─────────────────────────────────────────────────────────────────────────────
148+
release:
149+
needs: [build, sbom]
150+
runs-on: ubuntu-latest
151+
permissions:
152+
contents: write
153+
154+
steps:
155+
- name: Checkout
156+
uses: actions/checkout@v4
157+
158+
- name: Download SBOM
159+
uses: actions/download-artifact@v4
160+
with:
161+
name: sbom
162+
path: sbom
163+
164+
- name: Create Release
165+
uses: softprops/action-gh-release@v1
166+
with:
167+
generate_release_notes: true
168+
files: |
169+
sbom/sbom.spdx.json
170+
sbom/sbom.cdx.json
171+
sbom/sbom.spdx.json.sig

0 commit comments

Comments
 (0)