|
1 | | -# This file was autogenerated by dist: https://axodotdev.github.io/cargo-dist |
2 | | -# |
3 | | -# Copyright 2022-2024, axodotdev |
4 | | -# SPDX-License-Identifier: MIT or Apache-2.0 |
5 | | -# |
6 | | -# CI that: |
7 | | -# |
8 | | -# * checks for a Git Tag that looks like a release |
9 | | -# * builds artifacts with dist (archives, installers, hashes) |
10 | | -# * uploads those artifacts to temporary workflow zip |
11 | | -# * on success, uploads the artifacts to a GitHub Release |
12 | | -# |
13 | | -# Note that the GitHub Release will be created with a generated |
14 | | -# title/body based on your changelogs. |
15 | | - |
16 | 1 | name: Release |
17 | | -permissions: |
18 | | - "contents": "write" |
19 | 2 |
|
20 | | -# This task will run whenever you push a git tag that looks like a version |
21 | | -# like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. |
22 | | -# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where |
23 | | -# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION |
24 | | -# must be a Cargo-style SemVer Version (must have at least major.minor.patch). |
25 | | -# |
26 | | -# If PACKAGE_NAME is specified, then the announcement will be for that |
27 | | -# package (erroring out if it doesn't have the given version or isn't dist-able). |
28 | | -# |
29 | | -# If PACKAGE_NAME isn't specified, then the announcement will be for all |
30 | | -# (dist-able) packages in the workspace with that version (this mode is |
31 | | -# intended for workspaces with only one dist-able package, or with all dist-able |
32 | | -# packages versioned/released in lockstep). |
33 | | -# |
34 | | -# If you push multiple tags at once, separate instances of this workflow will |
35 | | -# spin up, creating an independent announcement for each one. However, GitHub |
36 | | -# will hard limit this to 3 tags per commit, as it will assume more tags is a |
37 | | -# mistake. |
38 | | -# |
39 | | -# If there's a prerelease-style suffix to the version, then the release(s) |
40 | | -# will be marked as a prerelease. |
41 | 3 | on: |
42 | 4 | push: |
43 | 5 | tags: |
44 | | - - '**[0-9]+.[0-9]+.[0-9]+*' |
| 6 | + - 'v[0-9]+.[0-9]+.[0-9]+*' |
| 7 | + |
| 8 | +permissions: |
| 9 | + contents: write |
45 | 10 |
|
46 | 11 | jobs: |
47 | | - # Run 'dist plan' (or host) to determine what tasks we need to do |
48 | | - plan: |
49 | | - runs-on: "ubuntu-22.04" |
50 | | - outputs: |
51 | | - val: ${{ steps.plan.outputs.manifest }} |
52 | | - tag: ${{ github.ref_name }} |
53 | | - tag-flag: ${{ format('--tag={0}', github.ref_name) }} |
54 | | - publishing: 'true' |
55 | | - env: |
56 | | - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 12 | + create-release: |
| 13 | + name: Create release |
| 14 | + runs-on: ubuntu-latest |
57 | 15 | steps: |
58 | | - - uses: actions/checkout@v6 |
59 | | - with: |
60 | | - persist-credentials: true |
61 | | - submodules: recursive |
62 | | - - name: Verify tag is on main branch |
| 16 | + - uses: actions/checkout@v4 |
| 17 | + - name: Verify tag matches Cargo.toml version |
63 | 18 | run: | |
64 | | - git fetch origin main --depth=50 |
65 | | - if ! git merge-base --is-ancestor "${{ github.sha }}" origin/main; then |
66 | | - echo "::error::Release tags must be pushed from the main branch. Aborting." |
| 19 | + TAG="${GITHUB_REF_NAME#v}" |
| 20 | + CARGO_VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/') |
| 21 | + if [ "$TAG" != "$CARGO_VERSION" ]; then |
| 22 | + echo "::error::Tag $GITHUB_REF_NAME does not match Cargo.toml version $CARGO_VERSION" |
67 | 23 | exit 1 |
68 | 24 | fi |
69 | | - - name: Install dist |
70 | | - # we specify bash to get pipefail; it guards against the `curl` command |
71 | | - # failing. otherwise `sh` won't catch that `curl` returned non-0 |
72 | | - shell: bash |
73 | | - run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.31.0/cargo-dist-installer.sh | sh" |
74 | | - - name: Cache dist |
75 | | - uses: actions/upload-artifact@v6 |
76 | | - with: |
77 | | - name: cargo-dist-cache |
78 | | - path: ~/.cargo/bin/dist |
79 | | - - id: plan |
| 25 | + - name: Create draft release |
| 26 | + env: |
| 27 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
80 | 28 | run: | |
81 | | - dist host --steps=create --tag=${{ github.ref_name }} --output-format=json > plan-dist-manifest.json |
82 | | - echo "dist ran successfully" |
83 | | - cat plan-dist-manifest.json |
84 | | - echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" |
85 | | - - name: "Upload dist-manifest.json" |
86 | | - uses: actions/upload-artifact@v6 |
87 | | - with: |
88 | | - name: artifacts-plan-dist-manifest |
89 | | - path: plan-dist-manifest.json |
| 29 | + gh release create "$GITHUB_REF_NAME" \ |
| 30 | + --draft \ |
| 31 | + --title "$GITHUB_REF_NAME" \ |
| 32 | + --generate-notes |
90 | 33 |
|
91 | | - # Build and packages all the platform-specific things |
92 | | - build-local-artifacts: |
93 | | - name: build-local-artifacts (${{ join(matrix.targets, ', ') }}) |
94 | | - # Let the initial task tell us to not run (currently very blunt) |
95 | | - needs: |
96 | | - - plan |
97 | | - if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null && (needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload') }} |
| 34 | + build-release: |
| 35 | + name: Build (${{ matrix.target }}) |
| 36 | + needs: create-release |
| 37 | + runs-on: ${{ matrix.os }} |
98 | 38 | strategy: |
99 | 39 | fail-fast: false |
100 | | - # Target platforms/runners are computed by dist in create-release. |
101 | | - # Each member of the matrix has the following arguments: |
102 | | - # |
103 | | - # - runner: the github runner |
104 | | - # - dist-args: cli flags to pass to dist |
105 | | - # - install-dist: expression to run to install dist on the runner |
106 | | - # |
107 | | - # Typically there will be: |
108 | | - # - 1 "global" task that builds universal installers |
109 | | - # - N "local" tasks that build each platform's binaries and platform-specific installers |
110 | | - matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }} |
111 | | - runs-on: ${{ matrix.runner }} |
112 | | - container: ${{ matrix.container && matrix.container.image || null }} |
113 | | - env: |
114 | | - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
115 | | - BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json |
| 40 | + matrix: |
| 41 | + include: |
| 42 | + - target: aarch64-apple-darwin |
| 43 | + os: macos-latest |
| 44 | + - target: x86_64-apple-darwin |
| 45 | + os: macos-13 |
| 46 | + - target: aarch64-unknown-linux-gnu |
| 47 | + os: ubuntu-latest |
| 48 | + use_cross: true |
| 49 | + - target: x86_64-unknown-linux-gnu |
| 50 | + os: ubuntu-latest |
| 51 | + - target: x86_64-unknown-linux-musl |
| 52 | + os: ubuntu-latest |
| 53 | + use_cross: true |
| 54 | + - target: x86_64-pc-windows-msvc |
| 55 | + os: windows-latest |
116 | 56 | steps: |
117 | | - - name: enable windows longpaths |
118 | | - run: | |
119 | | - git config --global core.longpaths true |
120 | | - - uses: actions/checkout@v6 |
121 | | - with: |
122 | | - persist-credentials: false |
123 | | - submodules: recursive |
124 | | - - name: Install Rust non-interactively if not already installed |
125 | | - if: ${{ matrix.container }} |
126 | | - run: | |
127 | | - if ! command -v cargo > /dev/null 2>&1; then |
128 | | - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y |
129 | | - echo "$HOME/.cargo/bin" >> $GITHUB_PATH |
130 | | - fi |
131 | | - - name: Install dist |
132 | | - run: ${{ matrix.install_dist.run }} |
133 | | - # Get the dist-manifest |
134 | | - - name: Fetch local artifacts |
135 | | - uses: actions/download-artifact@v7 |
136 | | - with: |
137 | | - pattern: artifacts-* |
138 | | - path: target/distrib/ |
139 | | - merge-multiple: true |
140 | | - - name: Install dependencies |
141 | | - run: | |
142 | | - ${{ matrix.packages_install }} |
143 | | - - name: Build artifacts |
144 | | - run: | |
145 | | - # Actually do builds and make zips and whatnot |
146 | | - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json |
147 | | - echo "dist ran successfully" |
148 | | - - id: cargo-dist |
149 | | - name: Post-build |
150 | | - # We force bash here just because github makes it really hard to get values up |
151 | | - # to "real" actions without writing to env-vars, and writing to env-vars has |
152 | | - # inconsistent syntax between shell and powershell. |
153 | | - shell: bash |
154 | | - run: | |
155 | | - # Parse out what we just built and upload it to scratch storage |
156 | | - echo "paths<<EOF" >> "$GITHUB_OUTPUT" |
157 | | - dist print-upload-files-from-manifest --manifest dist-manifest.json >> "$GITHUB_OUTPUT" |
158 | | - echo "EOF" >> "$GITHUB_OUTPUT" |
| 57 | + - uses: actions/checkout@v4 |
159 | 58 |
|
160 | | - cp dist-manifest.json "$BUILD_MANIFEST_NAME" |
161 | | - - name: "Upload artifacts" |
162 | | - uses: actions/upload-artifact@v6 |
163 | | - with: |
164 | | - name: artifacts-build-local-${{ join(matrix.targets, '_') }} |
165 | | - path: | |
166 | | - ${{ steps.cargo-dist.outputs.paths }} |
167 | | - ${{ env.BUILD_MANIFEST_NAME }} |
| 59 | + - name: Install Rust toolchain |
| 60 | + run: rustup target add ${{ matrix.target }} |
168 | 61 |
|
169 | | - # Build and package all the platform-agnostic(ish) things |
170 | | - build-global-artifacts: |
171 | | - needs: |
172 | | - - plan |
173 | | - - build-local-artifacts |
174 | | - runs-on: "ubuntu-22.04" |
175 | | - env: |
176 | | - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
177 | | - BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json |
178 | | - steps: |
179 | | - - uses: actions/checkout@v6 |
180 | | - with: |
181 | | - persist-credentials: false |
182 | | - submodules: recursive |
183 | | - - name: Install cached dist |
184 | | - uses: actions/download-artifact@v7 |
| 62 | + - name: Install cross |
| 63 | + if: matrix.use_cross |
| 64 | + uses: taiki-e/install-action@v2 |
185 | 65 | with: |
186 | | - name: cargo-dist-cache |
187 | | - path: ~/.cargo/bin/ |
188 | | - - run: chmod +x ~/.cargo/bin/dist |
189 | | - # Get all the local artifacts for the global tasks to use (for e.g. checksums) |
190 | | - - name: Fetch local artifacts |
191 | | - uses: actions/download-artifact@v7 |
192 | | - with: |
193 | | - pattern: artifacts-* |
194 | | - path: target/distrib/ |
195 | | - merge-multiple: true |
196 | | - - id: cargo-dist |
| 66 | + tool: cross |
| 67 | + |
| 68 | + - name: Build |
197 | 69 | shell: bash |
198 | 70 | run: | |
199 | | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json |
200 | | - echo "dist ran successfully" |
201 | | -
|
202 | | - # Parse out what we just built and upload it to scratch storage |
203 | | - echo "paths<<EOF" >> "$GITHUB_OUTPUT" |
204 | | - jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT" |
205 | | - echo "EOF" >> "$GITHUB_OUTPUT" |
| 71 | + if [ "${{ matrix.use_cross }}" = "true" ]; then |
| 72 | + cross build --release --target ${{ matrix.target }} |
| 73 | + else |
| 74 | + cargo build --release --target ${{ matrix.target }} |
| 75 | + fi |
206 | 76 |
|
207 | | - cp dist-manifest.json "$BUILD_MANIFEST_NAME" |
208 | | - - name: "Upload artifacts" |
209 | | - uses: actions/upload-artifact@v6 |
210 | | - with: |
211 | | - name: artifacts-build-global |
212 | | - path: | |
213 | | - ${{ steps.cargo-dist.outputs.paths }} |
214 | | - ${{ env.BUILD_MANIFEST_NAME }} |
215 | | - # Determines if we should publish/announce |
216 | | - host: |
217 | | - needs: |
218 | | - - plan |
219 | | - - build-local-artifacts |
220 | | - - build-global-artifacts |
221 | | - # Only run if we're "publishing", and only if plan, local and global didn't fail (skipped is fine) |
222 | | - if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} |
223 | | - env: |
224 | | - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
225 | | - runs-on: "ubuntu-22.04" |
226 | | - outputs: |
227 | | - val: ${{ steps.host.outputs.manifest }} |
228 | | - steps: |
229 | | - - uses: actions/checkout@v6 |
230 | | - with: |
231 | | - persist-credentials: false |
232 | | - submodules: recursive |
233 | | - - name: Install cached dist |
234 | | - uses: actions/download-artifact@v7 |
235 | | - with: |
236 | | - name: cargo-dist-cache |
237 | | - path: ~/.cargo/bin/ |
238 | | - - run: chmod +x ~/.cargo/bin/dist |
239 | | - # Fetch artifacts from scratch-storage |
240 | | - - name: Fetch artifacts |
241 | | - uses: actions/download-artifact@v7 |
242 | | - with: |
243 | | - pattern: artifacts-* |
244 | | - path: target/distrib/ |
245 | | - merge-multiple: true |
246 | | - - id: host |
| 77 | + - name: Package and checksum |
| 78 | + id: package |
247 | 79 | shell: bash |
248 | 80 | run: | |
249 | | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json |
250 | | - echo "artifacts uploaded and released successfully" |
251 | | - cat dist-manifest.json |
252 | | - echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" |
253 | | - - name: "Upload dist-manifest.json" |
254 | | - uses: actions/upload-artifact@v6 |
255 | | - with: |
256 | | - # Overwrite the previous copy |
257 | | - name: artifacts-dist-manifest |
258 | | - path: dist-manifest.json |
259 | | - # Create a GitHub Release while uploading all files to it |
260 | | - - name: "Download GitHub Artifacts" |
261 | | - uses: actions/download-artifact@v7 |
262 | | - with: |
263 | | - pattern: artifacts-* |
264 | | - path: artifacts |
265 | | - merge-multiple: true |
266 | | - - name: Cleanup |
267 | | - run: | |
268 | | - # Remove the granular manifests |
269 | | - rm -f artifacts/*-dist-manifest.json |
270 | | - - name: Create GitHub Release |
271 | | - env: |
272 | | - PRERELEASE_FLAG: "${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease && '--prerelease' || '' }}" |
273 | | - ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" |
274 | | - ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" |
275 | | - RELEASE_COMMIT: "${{ github.sha }}" |
276 | | - run: | |
277 | | - # Write and read notes from a file to avoid quoting breaking things |
278 | | - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt |
| 81 | + BIN="serpapi" |
| 82 | + TARGET="${{ matrix.target }}" |
| 83 | + VERSION="${GITHUB_REF_NAME#v}" |
| 84 | + PKG="${BIN}-${VERSION}-${TARGET}" |
| 85 | +
|
| 86 | + mkdir "$PKG" |
| 87 | + cp README.md LICENSE "$PKG/" |
279 | 88 |
|
280 | | - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* |
| 89 | + if [[ "$TARGET" == *"windows"* ]]; then |
| 90 | + cp "target/${TARGET}/release/${BIN}.exe" "$PKG/" |
| 91 | + 7z a "${PKG}.zip" "$PKG" |
| 92 | + ARCHIVE="${PKG}.zip" |
| 93 | + else |
| 94 | + cp "target/${TARGET}/release/${BIN}" "$PKG/" |
| 95 | + tar czf "${PKG}.tar.gz" "$PKG" |
| 96 | + ARCHIVE="${PKG}.tar.gz" |
| 97 | + fi |
281 | 98 |
|
| 99 | + sha256sum "$ARCHIVE" > "${ARCHIVE}.sha256" |
| 100 | + echo "archive=$ARCHIVE" >> "$GITHUB_OUTPUT" |
| 101 | + echo "sha256=${ARCHIVE}.sha256" >> "$GITHUB_OUTPUT" |
282 | 102 |
|
283 | | - announce: |
284 | | - needs: |
285 | | - - plan |
286 | | - - host |
287 | | - # use "always() && ..." to allow us to wait for all publish jobs while |
288 | | - # still allowing individual publish jobs to skip themselves (for prereleases). |
289 | | - # "host" however must run to completion, no skipping allowed! |
290 | | - if: ${{ always() && needs.host.result == 'success' }} |
291 | | - runs-on: "ubuntu-22.04" |
292 | | - env: |
293 | | - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
294 | | - steps: |
295 | | - - uses: actions/checkout@v6 |
296 | | - with: |
297 | | - persist-credentials: false |
298 | | - submodules: recursive |
| 103 | + - name: Upload to release |
| 104 | + env: |
| 105 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 106 | + run: | |
| 107 | + gh release upload "$GITHUB_REF_NAME" \ |
| 108 | + "${{ steps.package.outputs.archive }}" \ |
| 109 | + "${{ steps.package.outputs.sha256 }}" |
0 commit comments