main
yml 217 lines 6.75 KB
Raw
1 name: Release crates.io
2
3 # This is the only workflow that reacts to a tag push. It verifies the tag,
4 # publishes the crate, and then dispatches every distribution workflow with the
5 # same tag. Wrappers never publish for a crate release that failed.
6
7 on:
8 push:
9 tags:
10 - "v*.*.*"
11 workflow_dispatch:
12 inputs:
13 tag:
14 description: "Release tag (e.g. v0.4.0)"
15 required: true
16
17 permissions:
18 contents: read
19 actions: write
20
21 concurrency:
22 group: release-crates-${{ github.ref }}
23 cancel-in-progress: false
24
25 env:
26 CARGO_TERM_COLOR: always
27 ONDE_APP_ID: ${{ secrets.ONDE_APP_ID }}
28 ONDE_APP_SECRET: ${{ secrets.ONDE_APP_SECRET }}
29 GRESIQ_API_KEY: ${{ secrets.GRESIQ_API_KEY }}
30 GRESIQ_API_SECRET: ${{ secrets.GRESIQ_API_SECRET }}
31 HF_TOKEN: ${{ secrets.HF_TOKEN }}
32
33 jobs:
34 verify:
35 name: Verify release
36 runs-on: ubuntu-latest
37 outputs:
38 version: ${{ steps.release.outputs.version }}
39 tag: ${{ steps.release.outputs.tag }}
40 steps:
41 - name: Checkout
42 uses: actions/checkout@v6
43 with:
44 ref: ${{ github.event.inputs.tag || github.ref }}
45
46 - name: Read Rust toolchain
47 shell: bash
48 run: |
49 rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
50 if [ -z "$rust_toolchain" ]; then
51 echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2
52 exit 1
53 fi
54 echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
55
56 - name: Install Rust toolchain
57 uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
58 with:
59 toolchain: ${{ env.RUST_TOOLCHAIN }}
60 components: clippy, rustfmt
61
62 - name: Cache cargo registry and build artifacts
63 uses: Swatinem/rust-cache@v2
64
65 - name: Set the release version
66 id: release
67 shell: bash
68 run: |
69 if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
70 release_tag="${GITHUB_REF_NAME}"
71 else
72 release_tag="${{ github.event.inputs.tag }}"
73 release_tag="${release_tag#refs/tags/}"
74 fi
75 release_version="${release_tag#v}"
76
77 echo "tag=${release_tag}" >> "$GITHUB_OUTPUT"
78 echo "version=${release_version}" >> "$GITHUB_OUTPUT"
79
80 - name: Ensure tag matches Cargo.toml version
81 shell: bash
82 run: |
83 version="$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -n 1)"
84 if [ -z "$version" ]; then
85 echo "::error::Failed to read package version from Cargo.toml"
86 exit 1
87 fi
88 if [ "$version" != "${{ steps.release.outputs.version }}" ]; then
89 echo "::error::Cargo.toml is ${version} but the tag is ${{ steps.release.outputs.version }}"
90 exit 1
91 fi
92
93 - name: Ensure the pub.dev wrapper matches the tag
94 shell: bash
95 run: |
96 pub_version="$(sed -n 's/^version: \(.*\)/\1/p' pub/onde_cli/pubspec.yaml | head -n 1)"
97 if [ "$pub_version" != "${{ steps.release.outputs.version }}" ]; then
98 echo "::error::pubspec.yaml is ${pub_version} but the tag is ${{ steps.release.outputs.version }}"
99 exit 1
100 fi
101
102 - name: Check formatting
103 run: cargo fmt --all -- --check
104
105 - name: Run clippy
106 run: cargo clippy --all-targets --all-features -- -D warnings
107
108 - name: Run tests
109 run: cargo test --all-features --locked --verbose
110
111 - name: Run cargo check
112 run: cargo check --locked
113
114 - name: Verify package contents
115 run: cargo package --locked --allow-dirty
116
117 publish:
118 name: Publish to crates.io
119 runs-on: ubuntu-latest
120 needs: verify
121 environment:
122 name: crates-io
123 permissions:
124 contents: read
125 steps:
126 - name: Checkout
127 uses: actions/checkout@v6
128 with:
129 ref: ${{ github.event.inputs.tag || github.ref }}
130
131 - name: Read Rust toolchain
132 shell: bash
133 run: |
134 rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
135 echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
136
137 - name: Install Rust toolchain
138 uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
139 with:
140 toolchain: ${{ env.RUST_TOOLCHAIN }}
141
142 - name: Cache cargo registry and build artifacts
143 uses: Swatinem/rust-cache@v2
144
145 - name: Publish crate
146 env:
147 CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
148 shell: bash
149 run: |
150 version="${{ needs.verify.outputs.version }}"
151 if curl -sSf "https://crates.io/api/v1/crates/onde-cli/${version}" >/dev/null 2>&1; then
152 echo "onde-cli ${version} is already on crates.io, skipping publish"
153 exit 0
154 fi
155 cargo publish --locked
156
157 dispatch-distributions:
158 name: Trigger distribution workflows
159 needs: [verify, publish]
160 runs-on: ubuntu-latest
161
162 steps:
163 - name: Trigger GitHub release
164 uses: actions/github-script@v7
165 with:
166 script: |
167 await github.rest.actions.createWorkflowDispatch({
168 owner: context.repo.owner,
169 repo: context.repo.repo,
170 workflow_id: 'release-github.yml',
171 ref: '${{ needs.verify.outputs.tag }}',
172 inputs: {
173 tag: '${{ needs.verify.outputs.tag }}'
174 }
175 })
176
177 - name: Trigger npm release
178 uses: actions/github-script@v7
179 with:
180 script: |
181 await github.rest.actions.createWorkflowDispatch({
182 owner: context.repo.owner,
183 repo: context.repo.repo,
184 workflow_id: 'release-npm.yml',
185 ref: '${{ needs.verify.outputs.tag }}',
186 inputs: {
187 tag: '${{ needs.verify.outputs.tag }}'
188 }
189 })
190
191 - name: Trigger NuGet release
192 uses: actions/github-script@v7
193 with:
194 script: |
195 await github.rest.actions.createWorkflowDispatch({
196 owner: context.repo.owner,
197 repo: context.repo.repo,
198 workflow_id: 'release-nuget.yml',
199 ref: '${{ needs.verify.outputs.tag }}',
200 inputs: {
201 tag: '${{ needs.verify.outputs.tag }}'
202 }
203 })
204
205 - name: Trigger PyPI release
206 uses: actions/github-script@v7
207 with:
208 script: |
209 await github.rest.actions.createWorkflowDispatch({
210 owner: context.repo.owner,
211 repo: context.repo.repo,
212 workflow_id: 'release-pypi.yml',
213 ref: '${{ needs.verify.outputs.tag }}',
214 inputs: {
215 tag: '${{ needs.verify.outputs.tag }}'
216 }
217 })