-
Notifications
You must be signed in to change notification settings - Fork 4
203 lines (179 loc) · 6.09 KB
/
Copy pathrelease.yml
File metadata and controls
203 lines (179 loc) · 6.09 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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# SPDX-FileCopyrightText: 2026 Roman Valls Guimera <brainstorm@nopcode.org>
#
# SPDX-License-Identifier: GPL-3.0-or-later
# Release workflow: builds pre-compiled firmware binaries for all ports/targets,
# generates an SBOM (SPDX) using Anchore Syft, and attaches everything to a
# GitHub Release.
#
# Triggered by pushing a version tag (e.g. v0.3.0).
#
# NOTE on release-plz: release-plz is designed for publishing Rust *crates* to
# crates.io (version bumping, changelogs, cargo publish). Since ssh-stamp is a
# no_std firmware project whose artifacts are flashable .bin/.elf images rather
# than library crates, release-plz is not a good fit. Instead this workflow uses
# a tag-driven approach with softprops/action-gh-release.
#
# SBOM tooling: anchore/sbom-action runs Syft on the source tree (Cargo.lock
# + Cargo.toml) to produce an SPDX JSON SBOM covering all Rust dependencies.
# The resulting sbom.spdx.json can be fed into bootlin/sbom-cve-check for
# downstream CVE analysis, which this workflow runs automatically on every
# release.
name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag_name:
description: 'Tag name for the release (e.g. v0.3.0)'
required: true
permissions:
contents: read
jobs:
generate-sbom:
name: Generate SBOM
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Generate SPDX SBOM with Syft
uses: anchore/sbom-action@v0
with:
path: .
format: spdx-json
artifact-name: sbom.spdx.json
output-file: sbom.spdx.json
upload-artifact: true
upload-release-assets: false
build-firmware:
name: Build ${{ matrix.target.soc }}
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
fail-fast: false
matrix:
target:
- soc: esp32c6
toolchain: stable
triple: riscv32imac-unknown-none-elf
profile: release
- soc: esp32c2
toolchain: stable
triple: riscv32imc-unknown-none-elf
profile: release
- soc: esp32c3
toolchain: stable
triple: riscv32imc-unknown-none-elf
profile: release
- soc: esp32
toolchain: esp
triple: xtensa-esp32-none-elf
profile: release
- soc: esp32s2
toolchain: esp
triple: xtensa-esp32s2-none-elf
profile: esp32s2
- soc: esp32s3
toolchain: esp
triple: xtensa-esp32s3-none-elf
profile: release
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Cache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Setup Rust toolchain for RISC-V
if: ${{ !contains(fromJson('["esp32", "esp32s2", "esp32s3"]'), matrix.target.soc) }}
uses: dtolnay/rust-toolchain@v1
with:
target: ${{ matrix.target.triple }}
toolchain: stable
components: rust-src
- name: Setup Rust toolchain for Xtensa
if: ${{ contains(fromJson('["esp32", "esp32s2", "esp32s3"]'), matrix.target.soc) }}
uses: esp-rs/xtensa-toolchain@v1.7.0
with:
ldproxy: false
version: 1.95.0.0
- name: Build firmware
run: cargo +${{ matrix.target.toolchain }} build-${{ matrix.target.soc }}
- name: Install espflash
uses: taiki-e/install-action@v2
with:
tool: espflash
- name: Generate .bin image from ELF
run: |
mkdir -p release-assets
ELF_PATH="target/${{ matrix.target.triple }}/${{ matrix.target.profile }}/ssh-stamp-esp32"
espflash save-image --chip ${{ matrix.target.soc }} --partition-table ssh-stamp-esp32/partitions.csv "$ELF_PATH" "release-assets/ssh-stamp-${{ matrix.target.soc }}.bin"
cp "$ELF_PATH" "release-assets/ssh-stamp-${{ matrix.target.soc }}.elf"
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: firmware-${{ matrix.target.soc }}
path: release-assets/
retention-days: 1
cve-check:
name: CVE check
needs: [generate-sbom]
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Download SBOM artifact
uses: actions/download-artifact@v4
with:
name: sbom.spdx.json
- name: Install sbom-cve-check
run: pip install "sbom-cve-check[extra]"
- name: Run CVE analysis
run: sbom-cve-check --sbom-path sbom.spdx.json --export-type spdx --export-path cve-report.spdx.json
- name: Upload CVE report
uses: actions/upload-artifact@v4
with:
name: cve-report
path: cve-report.spdx.json
publish-release:
name: Publish GitHub Release
needs: [generate-sbom, build-firmware, cve-check]
runs-on: ubuntu-latest
permissions:
contents: write
actions: read
steps:
- name: Determine tag name
id: tag
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "name=${{ inputs.tag_name }}" >> "$GITHUB_OUTPUT"
else
echo "name=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
fi
- name: Download SBOM artifact
uses: actions/download-artifact@v4
with:
name: sbom.spdx.json
path: release-assets/
- name: Download CVE report artifact
uses: actions/download-artifact@v4
with:
name: cve-report
path: release-assets/
- name: Download all firmware artifacts
uses: actions/download-artifact@v4
with:
pattern: firmware-*
path: release-assets/
merge-multiple: true
- name: List release assets
run: ls -la release-assets/
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.tag.outputs.name }}
files: release-assets/*
generate_release_notes: true