Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 49a9d73

Browse files
authored
CI: Add manual workflow to publish crates (#7184)
* CI: Add manual workflow to publish crates #### Problem There are a lot of crates in SPL, and in the future SDK monorepo, so it would be extremely useful to have a manual GitHub Actions workflow to test a package, bump its version everywhere, publish it, and create a release on GitHub. #### Summary of changes Following the excellent scripts at the [counter-shank repo](https://github.com/solana-program/counter-shank/blob/main/.github/workflows/publish-rust-client.yml), port the zx bits to bash, and do mostly the same thing, except allowing for multiple packages to be published. Thanks @lorisleiva! * Oops, update the tag prefix for SPL
1 parent b22fbfe commit 49a9d73

File tree

2 files changed

+256
-0
lines changed

2 files changed

+256
-0
lines changed

.github/workflows/publish-rust.yml

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
name: Publish Rust Crate
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
package_path:
7+
description: Path to directory with package to release
8+
required: true
9+
type: string
10+
level:
11+
description: Level
12+
required: true
13+
default: patch
14+
type: choice
15+
options:
16+
- patch
17+
- minor
18+
- major
19+
- rc
20+
- beta
21+
- alpha
22+
- release
23+
- version
24+
version:
25+
description: Version (used with level "version")
26+
required: false
27+
type: string
28+
dry_run:
29+
description: Dry run
30+
required: true
31+
default: true
32+
type: boolean
33+
create_release:
34+
description: Create a GitHub release
35+
required: true
36+
type: boolean
37+
default: true
38+
39+
jobs:
40+
rustfmt:
41+
runs-on: ubuntu-latest
42+
steps:
43+
- uses: actions/checkout@v4
44+
45+
- name: Set env vars
46+
run: |
47+
source ci/rust-version.sh
48+
echo "RUST_NIGHTLY=$rust_nightly" >> $GITHUB_ENV
49+
50+
- uses: dtolnay/rust-toolchain@master
51+
with:
52+
toolchain: ${{ env.RUST_NIGHTLY }}
53+
components: rustfmt
54+
55+
- name: Run fmt
56+
run: ./cargo-nightly fmt --all -- --check
57+
58+
clippy:
59+
runs-on: ubuntu-latest
60+
steps:
61+
- uses: actions/checkout@v4
62+
63+
- name: Set env vars
64+
run: |
65+
source ci/rust-version.sh
66+
echo "RUST_NIGHTLY=$rust_nightly" >> $GITHUB_ENV
67+
68+
- uses: dtolnay/rust-toolchain@master
69+
with:
70+
toolchain: ${{ env.RUST_NIGHTLY }}
71+
components: clippy
72+
73+
- uses: actions/cache@v4
74+
with:
75+
path: |
76+
~/.cargo/registry
77+
~/.cargo/git
78+
target
79+
key: cargo-clippy-${{ hashFiles('**/Cargo.lock') }}
80+
restore-keys: |
81+
cargo-clippy-
82+
83+
- name: Install dependencies
84+
run: ./ci/install-build-deps.sh
85+
86+
- name: Run clippy
87+
run: ./cargo-nightly clippy -Zunstable-options --workspace --all-targets --features test-sbf -- --deny=warnings --deny=clippy::arithmetic_side_effects
88+
89+
cargo-build-test:
90+
runs-on: ubuntu-latest
91+
steps:
92+
- uses: actions/checkout@v4
93+
94+
- name: Remove unneeded packages for more space
95+
run: bash ./ci/warning/purge-ubuntu-runner.sh
96+
97+
- name: Set env vars
98+
run: |
99+
source ci/rust-version.sh
100+
echo "RUST_STABLE=$rust_stable" >> $GITHUB_ENV
101+
source ci/solana-version.sh
102+
echo "SOLANA_VERSION=$solana_version" >> $GITHUB_ENV
103+
104+
- uses: dtolnay/rust-toolchain@master
105+
with:
106+
toolchain: ${{ env.RUST_STABLE }}
107+
108+
- uses: actions/cache@v4
109+
with:
110+
path: |
111+
~/.cargo/registry
112+
~/.cargo/git
113+
key: cargo-build-${{ hashFiles('**/Cargo.lock') }}-${{ env.RUST_STABLE }}
114+
115+
- uses: actions/cache@v4
116+
with:
117+
path: |
118+
~/.cargo/bin/rustfilt
119+
key: cargo-sbf-bins-${{ runner.os }}
120+
121+
- uses: actions/cache@v4
122+
with:
123+
path: ~/.cache/solana
124+
key: solana-${{ env.SOLANA_VERSION }}
125+
126+
- name: Install dependencies
127+
run: |
128+
./ci/install-build-deps.sh
129+
./ci/install-program-deps.sh
130+
echo "$HOME/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH
131+
132+
- name: Build and test
133+
run: ./ci/cargo-build-test.sh
134+
135+
publish_crate:
136+
name: Publish crate
137+
runs-on: ubuntu-latest
138+
needs: [rustfmt, clippy, cargo-build-test]
139+
permissions:
140+
contents: write
141+
steps:
142+
- name: Git Checkout
143+
uses: actions/checkout@v4
144+
145+
- uses: dtolnay/rust-toolchain@master
146+
with:
147+
toolchain: ${{ env.RUST_STABLE }}
148+
149+
- uses: actions/cache@v4
150+
with:
151+
path: |
152+
~/.cargo/bin/
153+
~/.cargo/registry
154+
~/.cargo/git
155+
key: cargo-publish-${{ hashFiles('**/Cargo.lock') }}
156+
restore-keys: |
157+
cargo-publish-
158+
159+
- name: Install Cargo Release
160+
run: which cargo-release || cargo install cargo-release
161+
162+
- name: Ensure CARGO_REGISTRY_TOKEN variable is set
163+
env:
164+
token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
165+
if: ${{ env.token == '' }}
166+
run: |
167+
echo "The CARGO_REGISTRY_TOKEN secret variable is not set"
168+
echo "Go to \"Settings\" -> \"Secrets and variables\" -> \"Actions\" -> \"New repository secret\"."
169+
exit 1
170+
171+
- name: Set Git Author
172+
run: |
173+
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
174+
git config --global user.name "github-actions[bot]"
175+
176+
- name: Publish Crate
177+
id: publish
178+
env:
179+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
180+
run: |
181+
if [ "${{ inputs.level }}" == "version" ]; then
182+
LEVEL=${{ inputs.version }}
183+
else
184+
LEVEL=${{ inputs.level }}
185+
fi
186+
187+
if [ "${{ inputs.dry_run }}" == "true" ]; then
188+
OPTIONS="--dry-run"
189+
else
190+
OPTIONS=""
191+
fi
192+
193+
./ci/publish-rust.sh "${{ inputs.package_path }}" $LEVEL $OPTIONS
194+
195+
- name: Push Commit and Tag
196+
if: github.event.inputs.dry_run != 'true'
197+
run: git push origin --follow-tags
198+
199+
- name: Create GitHub release
200+
if: github.event.inputs.create_release == 'true' && github.event.inputs.dry_run != 'true'
201+
uses: ncipollo/release-action@v1
202+
with:
203+
tag: ${{ steps.publish.outputs.new_git_tag }}

ci/publish-rust.sh

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
base="$(dirname "${BASH_SOURCE[0]}")"
5+
source "$base/read-cargo-variable.sh"
6+
cd "$base/.."
7+
8+
if [[ -z $1 ]]; then
9+
echo 'A package manifest path — e.g. "token/program" — must be provided.'
10+
exit 1
11+
fi
12+
PACKAGE_PATH=$1
13+
if [[ -z $2 ]]; then
14+
echo 'A version level — e.g. "patch" — must be provided.'
15+
exit 1
16+
fi
17+
LEVEL=$2
18+
DRY_RUN=$3
19+
20+
# Go to the directory
21+
cd "${PACKAGE_PATH}"
22+
23+
# Publish the new version.
24+
if [[ -n ${DRY_RUN} ]]; then
25+
cargo release ${LEVEL}
26+
else
27+
cargo release ${LEVEL} --no-push --no-tag --no-confirm --execute
28+
fi
29+
30+
# Stop here if this is a dry run.
31+
if [[ -n $DRY_RUN ]]; then
32+
exit 0
33+
fi
34+
35+
# Get the new version.
36+
new_version=$(readCargoVariable version "Cargo.toml")
37+
package_name=$(readCargoVariable name "Cargo.toml")
38+
tag_name="$(echo $package_name | sed 's/spl-//')"
39+
new_git_tag="${tag_name}@v${new_version}"
40+
41+
# Expose the new version to CI if needed.
42+
if [[ -n $CI ]]; then
43+
echo "new_git_tag=${new_git_tag}" >> $GITHUB_OUTPUT
44+
fi
45+
46+
# Soft reset the last commit so we can create our own commit and tag.
47+
git reset --soft HEAD~1
48+
49+
# Commit the new version.
50+
git commit -am "Publish ${tag_name} v${new_version}"
51+
52+
# Tag the new version.
53+
git tag -a ${new_git_tag} -m "${tag_name} v${new_version}"

0 commit comments

Comments
 (0)