Skip to content

Commit ed898da

Browse files
committed
ci(release): rewrite workflow based on deps-lsp
1 parent c1fbf03 commit ed898da

1 file changed

Lines changed: 175 additions & 135 deletions

File tree

.github/workflows/release.yml

Lines changed: 175 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,23 @@ on:
55
tags:
66
- 'v*.*.*'
77

8-
permissions:
9-
contents: write
10-
id-token: write # Required for trusted publishing to crates.io
11-
128
env:
139
CARGO_TERM_COLOR: always
14-
CARGO_INCREMENTAL: 0
15-
CARGO_NET_RETRY: 10
16-
RUSTUP_MAX_RETRIES: 10
10+
11+
permissions:
12+
contents: write
1713

1814
jobs:
15+
# Create GitHub Release
1916
create-release:
2017
name: Create Release
2118
runs-on: ubuntu-latest
2219
outputs:
2320
upload_url: ${{ steps.create_release.outputs.upload_url }}
2421
version: ${{ steps.get_version.outputs.version }}
2522
steps:
23+
- uses: actions/checkout@v6
24+
2625
- name: Get version from tag
2726
id: get_version
2827
run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
@@ -31,179 +30,220 @@ jobs:
3130
id: create_release
3231
uses: softprops/action-gh-release@v2
3332
with:
34-
tag_name: ${{ github.ref }}
35-
name: Release v${{ steps.get_version.outputs.version }}
3633
draft: false
3734
prerelease: false
3835
generate_release_notes: true
39-
env:
40-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
41-
42-
publish-crate:
43-
name: Publish to crates.io
44-
runs-on: ubuntu-latest
45-
timeout-minutes: 20
46-
# Optional: use environment for additional protection
47-
# environment: release
48-
steps:
49-
- uses: actions/checkout@v6
50-
51-
- name: Install Rust stable
52-
uses: dtolnay/rust-toolchain@stable
53-
54-
- name: Cache Cargo
55-
uses: Swatinem/rust-cache@v2
56-
with:
57-
shared-key: "publish"
58-
59-
# Trusted Publishing: get short-lived token via OIDC
60-
- name: Authenticate with crates.io
61-
uses: rust-lang/crates-io-auth-action@v1
62-
63-
- name: Publish mcpls-core
64-
run: cargo publish --package mcpls-core
65-
66-
- name: Wait for mcpls-core to be available on crates.io
67-
run: sleep 60
36+
name: Release v${{ steps.get_version.outputs.version }}
6837

69-
- name: Verify mcpls-core is indexed
70-
run: |
71-
for i in {1..10}; do
72-
if cargo search mcpls-core | grep -q "mcpls-core"; then
73-
echo "mcpls-core is indexed"
74-
exit 0
75-
fi
76-
echo "Waiting for mcpls-core to be indexed (attempt $i/10)..."
77-
sleep 30
78-
done
79-
echo "mcpls-core not indexed after 5 minutes, proceeding anyway"
80-
81-
- name: Publish mcpls
82-
run: cargo publish --package mcpls
83-
84-
build-release:
85-
name: Build Release Binary (${{ matrix.name }})
38+
# Build cross-platform binaries
39+
build-binaries:
40+
name: Build (${{ matrix.target }})
8641
needs: create-release
8742
runs-on: ${{ matrix.os }}
88-
timeout-minutes: 30
43+
timeout-minutes: 45
8944
strategy:
9045
fail-fast: false
9146
matrix:
9247
include:
93-
# Linux x86_64 (GNU)
94-
- target: x86_64-unknown-linux-gnu
95-
os: ubuntu-latest
96-
name: linux-x86_64
97-
archive_ext: tar.gz
98-
99-
# Linux x86_64 (musl - static binary)
100-
- target: x86_64-unknown-linux-musl
101-
os: ubuntu-latest
102-
name: linux-x86_64-musl
103-
archive_ext: tar.gz
104-
105-
# macOS x86_64 (Intel)
106-
- target: x86_64-apple-darwin
107-
os: macos-latest
108-
name: macos-x86_64
109-
archive_ext: tar.gz
110-
111-
# macOS aarch64 (Apple Silicon)
112-
- target: aarch64-apple-darwin
113-
os: macos-latest
114-
name: macos-aarch64
115-
archive_ext: tar.gz
48+
# Linux x86_64
49+
- os: ubuntu-latest
50+
target: x86_64-unknown-linux-gnu
51+
archive: tar.gz
52+
use_cross: false
53+
54+
# Linux aarch64
55+
- os: ubuntu-latest
56+
target: aarch64-unknown-linux-gnu
57+
archive: tar.gz
58+
use_cross: true
59+
60+
# macOS x86_64
61+
- os: macos-latest
62+
target: x86_64-apple-darwin
63+
archive: tar.gz
64+
use_cross: false
65+
66+
# macOS aarch64 (M1/M2)
67+
- os: macos-latest
68+
target: aarch64-apple-darwin
69+
archive: tar.gz
70+
use_cross: false
11671

11772
# Windows x86_64
118-
- target: x86_64-pc-windows-msvc
119-
os: windows-latest
120-
name: windows-x86_64
121-
archive_ext: zip
73+
- os: windows-latest
74+
target: x86_64-pc-windows-msvc
75+
archive: zip
76+
use_cross: false
77+
78+
# Windows aarch64 (ARM64)
79+
- os: windows-latest
80+
target: aarch64-pc-windows-msvc
81+
archive: zip
82+
use_cross: false
12283

12384
steps:
12485
- uses: actions/checkout@v6
12586

126-
- name: Install Rust stable
87+
- name: Install Rust
12788
uses: dtolnay/rust-toolchain@stable
12889
with:
12990
targets: ${{ matrix.target }}
13091

92+
- name: Install cargo-binstall
93+
uses: cargo-bins/cargo-binstall@main
94+
95+
- name: Install cross (for cross-compilation)
96+
if: matrix.use_cross
97+
run: cargo binstall --no-confirm cross
98+
13199
- name: Cache Cargo
132100
uses: Swatinem/rust-cache@v2
133101
with:
134102
shared-key: "release-${{ matrix.target }}"
135103

136-
- name: Install musl-tools (Linux musl)
137-
if: matrix.target == 'x86_64-unknown-linux-musl'
138-
run: sudo apt-get update && sudo apt-get install -y musl-tools
139-
140-
- name: Build release binary
141-
run: cargo build --release --target ${{ matrix.target }} --package mcpls
104+
- name: Build release (cross)
105+
if: matrix.use_cross
106+
run: cross build --package mcpls --release --target ${{ matrix.target }}
142107

143-
- name: Strip binary (Unix)
144-
if: runner.os != 'Windows'
145-
run: strip target/${{ matrix.target }}/release/mcpls
108+
- name: Build release (native)
109+
if: "!matrix.use_cross"
110+
run: cargo build --package mcpls --release --target ${{ matrix.target }}
146111

147112
- name: Get binary name
148-
id: get_binary
149-
shell: bash
113+
id: binary
150114
run: |
151-
if [[ "${{ runner.os }}" == "Windows" ]]; then
152-
echo "binary=mcpls.exe" >> $GITHUB_OUTPUT
115+
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
116+
echo "name=mcpls.exe" >> $GITHUB_OUTPUT
153117
else
154-
echo "binary=mcpls" >> $GITHUB_OUTPUT
118+
echo "name=mcpls" >> $GITHUB_OUTPUT
155119
fi
156-
157-
- name: Check binary size
158120
shell: bash
159-
run: |
160-
ls -lh target/${{ matrix.target }}/release/${{ steps.get_binary.outputs.binary }}
161-
du -sh target/${{ matrix.target }}/release/${{ steps.get_binary.outputs.binary }}
121+
122+
- name: Strip binary (Linux/macOS, native only)
123+
if: matrix.os != 'windows-latest' && !matrix.use_cross
124+
run: strip target/${{ matrix.target }}/release/${{ steps.binary.outputs.name }}
162125

163126
- name: Create archive (Unix)
164-
if: matrix.archive_ext == 'tar.gz'
127+
if: matrix.archive == 'tar.gz'
165128
run: |
166129
cd target/${{ matrix.target }}/release
167-
tar czf mcpls-${{ needs.create-release.outputs.version }}-${{ matrix.name }}.tar.gz mcpls
168-
mv mcpls-${{ needs.create-release.outputs.version }}-${{ matrix.name }}.tar.gz ../../..
130+
tar czf ../../../mcpls-${{ matrix.target }}.tar.gz ${{ steps.binary.outputs.name }}
131+
cd ../../..
132+
shasum -a 256 mcpls-${{ matrix.target }}.tar.gz > mcpls-${{ matrix.target }}.tar.gz.sha256
169133
170134
- name: Create archive (Windows)
171-
if: matrix.archive_ext == 'zip'
172-
shell: bash
135+
if: matrix.archive == 'zip'
173136
run: |
174137
cd target/${{ matrix.target }}/release
175-
7z a mcpls-${{ needs.create-release.outputs.version }}-${{ matrix.name }}.zip mcpls.exe
176-
mv mcpls-${{ needs.create-release.outputs.version }}-${{ matrix.name }}.zip ../../../
177-
178-
- name: Upload artifact to workflow
179-
uses: actions/upload-artifact@v4
180-
with:
181-
name: mcpls-${{ needs.create-release.outputs.version }}-${{ matrix.name }}
182-
path: mcpls-${{ needs.create-release.outputs.version }}-${{ matrix.name }}.${{ matrix.archive_ext }}
183-
retention-days: 7
138+
7z a ../../../mcpls-${{ matrix.target }}.zip ${{ steps.binary.outputs.name }}
139+
cd ../../..
140+
certUtil -hashfile mcpls-${{ matrix.target }}.zip SHA256 > mcpls-${{ matrix.target }}.zip.sha256
141+
shell: cmd
184142

185-
- name: Upload to GitHub Release
143+
- name: Upload release archive
186144
uses: softprops/action-gh-release@v2
187145
with:
188-
tag_name: ${{ github.ref }}
189-
files: mcpls-${{ needs.create-release.outputs.version }}-${{ matrix.name }}.${{ matrix.archive_ext }}
190-
env:
191-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
192-
193-
# All release jobs passed
194-
release-success:
195-
name: Release Success
196-
needs: [create-release, publish-crate, build-release]
146+
files: |
147+
mcpls-${{ matrix.target }}.*
148+
149+
# Publish to crates.io using Trusted Publishing (OIDC)
150+
publish-crates:
151+
name: Publish to crates.io
152+
needs: [create-release, build-binaries]
197153
runs-on: ubuntu-latest
198-
if: always()
154+
timeout-minutes: 20
155+
permissions:
156+
contents: read
157+
id-token: write
199158
steps:
200-
- name: Check all jobs
159+
- uses: actions/checkout@v6
160+
161+
- name: Install Rust
162+
uses: dtolnay/rust-toolchain@stable
163+
164+
- name: Cache Cargo
165+
uses: Swatinem/rust-cache@v2
166+
167+
- name: Verify version matches tag
201168
run: |
202-
if [[ "${{ needs.create-release.result }}" != "success" ]] || \
203-
[[ "${{ needs.publish-crate.result }}" != "success" ]] || \
204-
[[ "${{ needs.build-release.result }}" != "success" ]]; then
205-
echo "One or more release jobs failed"
169+
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
170+
CARGO_VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
171+
if [ "$TAG_VERSION" != "$CARGO_VERSION" ]; then
172+
echo "Tag version ($TAG_VERSION) does not match Cargo.toml version ($CARGO_VERSION)"
206173
exit 1
207174
fi
208-
echo "All release jobs passed successfully!"
209-
echo "Version ${{ needs.create-release.outputs.version }} released!"
175+
176+
- name: Authenticate with crates.io
177+
id: crates-io-auth
178+
uses: rust-lang/crates-io-auth-action@v1
179+
180+
- name: Publish crates to crates.io
181+
uses: katyo/publish-crates@v2
182+
with:
183+
registry-token: ${{ steps.crates-io-auth.outputs.token }}
184+
ignore-unpublished-changes: true
185+
publish-delay: 10000
186+
187+
# Update release notes with installation instructions
188+
update-release-notes:
189+
name: Update Release Notes
190+
needs: [create-release, build-binaries, publish-crates]
191+
runs-on: ubuntu-latest
192+
steps:
193+
- uses: actions/checkout@v6
194+
195+
- name: Get version
196+
id: version
197+
run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
198+
199+
- name: Update release with installation instructions
200+
uses: softprops/action-gh-release@v2
201+
with:
202+
append_body: true
203+
body: |
204+
205+
## Installation
206+
207+
### Binary Installation
208+
209+
Download the appropriate binary for your platform from the assets below:
210+
211+
- **Linux x86_64**: `mcpls-x86_64-unknown-linux-gnu.tar.gz`
212+
- **Linux aarch64**: `mcpls-aarch64-unknown-linux-gnu.tar.gz`
213+
- **macOS x86_64**: `mcpls-x86_64-apple-darwin.tar.gz`
214+
- **macOS ARM64**: `mcpls-aarch64-apple-darwin.tar.gz`
215+
- **Windows x64**: `mcpls-x86_64-pc-windows-msvc.zip`
216+
- **Windows ARM64**: `mcpls-aarch64-pc-windows-msvc.zip`
217+
218+
Extract and add to your PATH:
219+
220+
```bash
221+
# Linux/macOS
222+
tar xzf mcpls-*.tar.gz
223+
sudo mv mcpls /usr/local/bin/
224+
225+
# Verify installation
226+
mcpls --version
227+
```
228+
229+
### Cargo Installation
230+
231+
```bash
232+
cargo install mcpls
233+
```
234+
235+
### Claude Code Integration
236+
237+
Add to `~/.claude/claude_desktop_config.json`:
238+
239+
```json
240+
{
241+
"mcpServers": {
242+
"mcpls": { "command": "mcpls", "args": [] }
243+
}
244+
}
245+
```
246+
247+
## Checksums
248+
249+
SHA256 checksums are available for all artifacts (`.sha256` files).

0 commit comments

Comments
 (0)