|
16 | 16 | RUST_BACKTRACE: 1 |
17 | 17 |
|
18 | 18 | jobs: |
19 | | - create-release: |
20 | | - name: Create Release |
21 | | - runs-on: ubuntu-latest |
22 | | - outputs: |
23 | | - version: ${{ steps.get_version.outputs.VERSION }} |
24 | | - changelog: ${{ steps.changelog.outputs.CHANGELOG }} |
25 | | - steps: |
26 | | - - name: Checkout code |
27 | | - uses: actions/checkout@v4 |
28 | | - with: |
29 | | - fetch-depth: 0 |
30 | | - |
31 | | - - name: Get version from tag |
32 | | - id: get_version |
33 | | - run: | |
34 | | - if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then |
35 | | - VERSION="${{ github.event.inputs.tag }}" |
36 | | - else |
37 | | - VERSION="${GITHUB_REF#refs/tags/}" |
38 | | - fi |
39 | | - echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT |
40 | | -
|
41 | | - - name: Validate semver format |
42 | | - run: | |
43 | | - VERSION="${{ steps.get_version.outputs.VERSION }}" |
44 | | - case "$VERSION" in |
45 | | - [0-9]*.[0-9]*.[0-9]*) ;; |
46 | | - *) |
47 | | - echo "Error: '$VERSION' is not a valid semver (expected X.Y.Z[-pre][+build])" |
48 | | - exit 1 |
49 | | - ;; |
50 | | - esac |
51 | | -
|
52 | | - - name: Generate changelog |
53 | | - id: changelog |
54 | | - run: | |
55 | | - PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") |
56 | | - if [ -z "$PREV_TAG" ]; then |
57 | | - CHANGELOG="Initial release" |
58 | | - else |
59 | | - CHANGELOG=$(git log "${PREV_TAG}"..HEAD --pretty=format:"- %s" --no-merges | head -50) |
60 | | - if [ -z "$CHANGELOG" ]; then |
61 | | - CHANGELOG="- No changes since last release" |
62 | | - fi |
63 | | - fi |
64 | | - CHANGELOG=$(printf '%s\n' "$CHANGELOG" | sed 's/%/%25/g; s/\r/%0D/g' | awk '{printf "%s%0A", $0}' | sed 's/%0A$//') |
65 | | - echo "CHANGELOG=$CHANGELOG" >> $GITHUB_OUTPUT |
66 | | -
|
67 | | - - name: Check if release exists |
68 | | - id: check_release |
69 | | - env: |
70 | | - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
71 | | - run: | |
72 | | - if gh release view "${{ steps.get_version.outputs.VERSION }}" >/dev/null 2>&1; then |
73 | | - echo "exists=true" >> $GITHUB_OUTPUT |
74 | | - else |
75 | | - echo "exists=false" >> $GITHUB_OUTPUT |
76 | | - fi |
77 | | -
|
78 | | - - name: Create Release (draft) |
79 | | - if: steps.check_release.outputs.exists == 'false' |
80 | | - env: |
81 | | - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
82 | | - run: | |
83 | | - VERSION="${{ steps.get_version.outputs.VERSION }}" |
84 | | - IS_PRE="false" |
85 | | - case "$VERSION" in |
86 | | - *-*|0.*) IS_PRE="true" ;; |
87 | | - esac |
88 | | - if [ "$IS_PRE" = "true" ]; then |
89 | | - gh release create "$VERSION" \ |
90 | | - --title "Release $VERSION" \ |
91 | | - --notes "${{ steps.changelog.outputs.CHANGELOG }}" \ |
92 | | - --draft --prerelease |
93 | | - else |
94 | | - gh release create "$VERSION" \ |
95 | | - --title "Release $VERSION" \ |
96 | | - --notes "${{ steps.changelog.outputs.CHANGELOG }}" \ |
97 | | - --draft |
98 | | - fi |
99 | | -
|
100 | 19 | build: |
101 | 20 | name: Build ${{ matrix.target }} |
102 | | - needs: create-release |
103 | 21 | runs-on: ${{ matrix.os }} |
104 | 22 | strategy: |
105 | 23 | fail-fast: false |
@@ -149,119 +67,31 @@ jobs: |
149 | 67 | run: | |
150 | 68 | mkdir -p dist |
151 | 69 | BIN_DIR="target/${{ matrix.target }}/release" |
152 | | - ARCHIVE="synx-${{ needs.create-release.outputs.version }}-${{ matrix.target }}.tar.gz" |
| 70 | + ARCHIVE="synx-${{ inputs.tag || github.ref_name }}-${{ matrix.target }}.tar.gz" |
153 | 71 | tar czf "dist/${ARCHIVE}" -C "${BIN_DIR}" synx |
154 | 72 | ls -la dist/ |
155 | 73 |
|
156 | | - - name: Upload release asset |
157 | | - env: |
158 | | - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
159 | | - run: | |
160 | | - gh release upload "${{ needs.create-release.outputs.version }}" \ |
161 | | - "dist/synx-${{ needs.create-release.outputs.version }}-${{ matrix.target }}.tar.gz" \ |
162 | | - --clobber |
163 | | -
|
164 | | - publish-crate: |
165 | | - name: Publish to crates.io |
166 | | - needs: [create-release, build] |
167 | | - runs-on: ubuntu-latest |
168 | | - steps: |
169 | | - - name: Checkout code |
170 | | - uses: actions/checkout@v4 |
171 | | - |
172 | | - - name: Install Rust |
173 | | - uses: dtolnay/rust-toolchain@stable |
174 | | - |
175 | | - - name: Cache dependencies |
176 | | - uses: actions/cache@v4 |
| 74 | + - name: Upload artifact |
| 75 | + uses: actions/upload-artifact@v4 |
177 | 76 | with: |
178 | | - path: | |
179 | | - ~/.cargo/registry |
180 | | - ~/.cargo/git |
181 | | - target |
182 | | - key: ${{ runner.os }}-cargo-publish-${{ hashFiles('**/Cargo.lock') }} |
183 | | - restore-keys: | |
184 | | - ${{ runner.os }}-cargo-publish- |
185 | | - ${{ runner.os }}-cargo- |
186 | | -
|
187 | | - - name: Validate Cargo.toml version matches tag |
188 | | - run: | |
189 | | - VERSION="${{ needs.create-release.outputs.version }}" |
190 | | - CARGO_VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/') |
191 | | - if [ "$VERSION" != "$CARGO_VERSION" ]; then |
192 | | - echo "::error::Tag $VERSION does not match Cargo.toml version $CARGO_VERSION" |
193 | | - exit 1 |
194 | | - fi |
195 | | - echo "Version validated: $VERSION" |
196 | | -
|
197 | | - - name: Check if already published |
198 | | - id: check_published |
199 | | - run: | |
200 | | - VERSION="${{ needs.create-release.outputs.version }}" |
201 | | - if cargo search synx --limit 1 | grep -q "^synx = \"$VERSION\""; then |
202 | | - echo "already_published=true" >> $GITHUB_OUTPUT |
203 | | - echo "::notice::Version $VERSION already on crates.io — skipping" |
204 | | - else |
205 | | - echo "already_published=false" >> $GITHUB_OUTPUT |
206 | | - fi |
207 | | -
|
208 | | - - name: Dry-run publish |
209 | | - if: steps.check_published.outputs.already_published == 'false' |
210 | | - env: |
211 | | - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} |
212 | | - run: cargo publish --dry-run |
| 77 | + name: release-${{ matrix.target }} |
| 78 | + path: dist/* |
| 79 | + if-no-files-found: error |
213 | 80 |
|
214 | | - - name: Publish |
215 | | - if: steps.check_published.outputs.already_published == 'false' |
216 | | - env: |
217 | | - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} |
218 | | - run: cargo publish |
219 | | - |
220 | | - finalize-release: |
221 | | - name: Finalize Release |
222 | | - needs: [create-release, build, publish-crate] |
223 | | - runs-on: ubuntu-latest |
224 | | - steps: |
225 | | - - name: Checkout code |
226 | | - uses: actions/checkout@v4 |
227 | | - |
228 | | - - name: Publish release (drop draft) with download links |
229 | | - env: |
230 | | - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
231 | | - run: | |
232 | | - VERSION="${{ needs.create-release.outputs.version }}" |
233 | | - cat > release_notes.md << EOF |
234 | | - ## What's changed |
235 | | -
|
236 | | - ${{ needs.create-release.outputs.changelog }} |
237 | | -
|
238 | | - ## Install |
239 | | -
|
240 | | - ### One-liner (Linux & macOS) |
241 | | - \`\`\`sh |
242 | | - curl -fsSL https://raw.githubusercontent.com/${{ github.repository }}/main/install.sh | sh |
243 | | - \`\`\` |
244 | | -
|
245 | | - ### From crates.io |
246 | | - \`\`\`sh |
247 | | - cargo install synx |
248 | | - \`\`\` |
249 | | -
|
250 | | - ### Manual download |
251 | | -
|
252 | | - | Platform | Architecture | Download | |
253 | | - |----------|--------------|----------| |
254 | | - | Linux | x86_64 (static musl) | [synx-${VERSION}-x86_64-unknown-linux-musl.tar.gz](https://github.com/${{ github.repository }}/releases/download/${VERSION}/synx-${VERSION}-x86_64-unknown-linux-musl.tar.gz) | |
255 | | - | Linux | aarch64 (static musl) | [synx-${VERSION}-aarch64-unknown-linux-musl.tar.gz](https://github.com/${{ github.repository }}/releases/download/${VERSION}/synx-${VERSION}-aarch64-unknown-linux-musl.tar.gz) | |
256 | | - | macOS | x86_64 | [synx-${VERSION}-x86_64-apple-darwin.tar.gz](https://github.com/${{ github.repository }}/releases/download/${VERSION}/synx-${VERSION}-x86_64-apple-darwin.tar.gz) | |
257 | | - | macOS | aarch64 (Apple Silicon) | [synx-${VERSION}-aarch64-apple-darwin.tar.gz](https://github.com/${{ github.repository }}/releases/download/${VERSION}/synx-${VERSION}-aarch64-apple-darwin.tar.gz) | |
258 | | -
|
259 | | - ### Verify |
260 | | - \`\`\`sh |
261 | | - synx --version |
262 | | - \`\`\` |
263 | | -
|
264 | | - Synx is a real-time bidirectional file sync over SSH. You need it |
265 | | - installed on **both** ends. See the README for usage. |
266 | | - EOF |
267 | | - gh release edit "$VERSION" --draft=false --notes-file release_notes.md |
| 81 | + publish-crate: |
| 82 | + name: Publish to Crates.io |
| 83 | + needs: build |
| 84 | + uses: muvon/ci-workflow/.github/workflows/rust-publish.yml@master |
| 85 | + secrets: inherit |
| 86 | + with: |
| 87 | + tag: ${{ inputs.tag }} |
| 88 | + toolchain: stable |
| 89 | + |
| 90 | + release: |
| 91 | + name: Create Release |
| 92 | + needs: [build, publish-crate] |
| 93 | + uses: muvon/ci-workflow/.github/workflows/release.yml@master |
| 94 | + with: |
| 95 | + tag: ${{ inputs.tag }} |
| 96 | + artifacts: 'release-*' |
| 97 | + draft: false |
0 commit comments