Skip to content

Commit 19f7d5f

Browse files
committed
chore(github): automate releases
1 parent 7e16877 commit 19f7d5f

File tree

2 files changed

+344
-0
lines changed

2 files changed

+344
-0
lines changed
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*.*.*"
7+
8+
env:
9+
CARGO_TERM_COLOR: always
10+
11+
jobs:
12+
test:
13+
name: Run tests
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
with:
19+
ref: ${{ github.ref }}
20+
21+
- name: Install Rust
22+
uses: dtolnay/rust-toolchain@stable
23+
24+
- name: Run tests
25+
run: cargo test --all-features --verbose
26+
27+
- name: Run clippy
28+
run: cargo clippy --all-features -- -D warnings
29+
30+
build-binaries:
31+
name: Build binaries
32+
needs: test
33+
strategy:
34+
matrix:
35+
include:
36+
# Linux
37+
- target: x86_64-unknown-linux-gnu
38+
os: ubuntu-latest
39+
name: sql-schema-x86_64-linux
40+
- target: aarch64-unknown-linux-gnu
41+
os: ubuntu-latest
42+
name: sql-schema-aarch64-linux
43+
# macOS
44+
- target: x86_64-apple-darwin
45+
os: macos-latest
46+
name: sql-schema-x86_64-macos
47+
- target: aarch64-apple-darwin
48+
os: macos-latest
49+
name: sql-schema-aarch64-macos
50+
# Windows
51+
- target: x86_64-pc-windows-msvc
52+
os: windows-latest
53+
name: sql-schema-x86_64-windows.exe
54+
- target: aarch64-pc-windows-msvc
55+
os: windows-latest
56+
name: sql-schema-aarch64-windows.exe
57+
58+
runs-on: ${{ matrix.os }}
59+
60+
steps:
61+
- uses: actions/checkout@v4
62+
with:
63+
ref: ${{ github.ref }}
64+
65+
- name: Install Rust
66+
uses: dtolnay/rust-toolchain@stable
67+
with:
68+
targets: ${{ matrix.target }}
69+
70+
- name: Install cross-compilation tools for aarch64-linux
71+
if: matrix.target == 'aarch64-unknown-linux-gnu'
72+
run: |
73+
sudo apt-get update
74+
sudo apt-get install -y gcc-aarch64-linux-gnu
75+
76+
- name: Build binary
77+
run: cargo build --release --target ${{ matrix.target }} --verbose
78+
env:
79+
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
80+
81+
- name: Prepare binary
82+
shell: bash
83+
run: |
84+
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
85+
cp target/${{ matrix.target }}/release/sql-schema.exe ${{ matrix.name }}
86+
else
87+
cp target/${{ matrix.target }}/release/sql-schema ${{ matrix.name }}
88+
fi
89+
90+
- name: Upload binary artifact
91+
uses: actions/upload-artifact@v4
92+
with:
93+
name: ${{ matrix.name }}
94+
path: ${{ matrix.name }}
95+
96+
create-release:
97+
name: Create GitHub Release
98+
needs: build-binaries
99+
runs-on: ubuntu-latest
100+
permissions:
101+
contents: write
102+
outputs:
103+
upload_url: ${{ steps.create_release.outputs.upload_url }}
104+
105+
steps:
106+
- uses: actions/checkout@v4
107+
with:
108+
ref: ${{ github.ref }}
109+
fetch-depth: 0 # Fetch all history for git-cliff
110+
111+
- name: Get version from tag
112+
id: get_version
113+
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
114+
115+
- name: Generate changelog
116+
id: git-cliff
117+
uses: orhun/git-cliff-action@v3
118+
with:
119+
config: cliff.toml
120+
args: --current --strip all
121+
env:
122+
OUTPUT: CHANGELOG.md
123+
124+
- name: Download all artifacts
125+
uses: actions/download-artifact@v4
126+
with:
127+
path: ./binaries
128+
129+
- name: Create Release
130+
id: create_release
131+
uses: actions/create-release@v1
132+
env:
133+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
134+
with:
135+
tag_name: ${{ github.ref }}
136+
release_name: Release ${{ steps.get_version.outputs.VERSION }}
137+
draft: false
138+
prerelease: false
139+
body: |
140+
## Changes in ${{ steps.get_version.outputs.VERSION }}
141+
142+
${{ steps.git-cliff.outputs.content }}
143+
144+
### Installation
145+
146+
#### From crates.io
147+
```bash
148+
cargo install sql-schema
149+
```
150+
151+
#### Binary downloads
152+
Download the appropriate binary for your platform from the assets below.
153+
154+
- name: Upload Linux x86_64 binary
155+
uses: actions/upload-release-asset@v1
156+
env:
157+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
158+
with:
159+
upload_url: ${{ steps.create_release.outputs.upload_url }}
160+
asset_path: ./binaries/sql-schema-x86_64-linux/sql-schema-x86_64-linux
161+
asset_name: sql-schema-x86_64-linux
162+
asset_content_type: application/octet-stream
163+
164+
- name: Upload Linux aarch64 binary
165+
uses: actions/upload-release-asset@v1
166+
env:
167+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
168+
with:
169+
upload_url: ${{ steps.create_release.outputs.upload_url }}
170+
asset_path: ./binaries/sql-schema-aarch64-linux/sql-schema-aarch64-linux
171+
asset_name: sql-schema-aarch64-linux
172+
asset_content_type: application/octet-stream
173+
174+
- name: Upload macOS x86_64 binary
175+
uses: actions/upload-release-asset@v1
176+
env:
177+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
178+
with:
179+
upload_url: ${{ steps.create_release.outputs.upload_url }}
180+
asset_path: ./binaries/sql-schema-x86_64-macos/sql-schema-x86_64-macos
181+
asset_name: sql-schema-x86_64-macos
182+
asset_content_type: application/octet-stream
183+
184+
- name: Upload macOS aarch64 binary
185+
uses: actions/upload-release-asset@v1
186+
env:
187+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
188+
with:
189+
upload_url: ${{ steps.create_release.outputs.upload_url }}
190+
asset_path: ./binaries/sql-schema-aarch64-macos/sql-schema-aarch64-macos
191+
asset_name: sql-schema-aarch64-macos
192+
asset_content_type: application/octet-stream
193+
194+
- name: Upload Windows x86_64 binary
195+
uses: actions/upload-release-asset@v1
196+
env:
197+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
198+
with:
199+
upload_url: ${{ steps.create_release.outputs.upload_url }}
200+
asset_path: ./binaries/sql-schema-x86_64-windows.exe/sql-schema-x86_64-windows.exe
201+
asset_name: sql-schema-x86_64-windows.exe
202+
asset_content_type: application/octet-stream
203+
204+
- name: Upload Windows aarch64 binary
205+
uses: actions/upload-release-asset@v1
206+
env:
207+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
208+
with:
209+
upload_url: ${{ steps.create_release.outputs.upload_url }}
210+
asset_path: ./binaries/sql-schema-aarch64-windows.exe/sql-schema-aarch64-windows.exe
211+
asset_name: sql-schema-aarch64-windows.exe
212+
asset_content_type: application/octet-stream
213+
214+
publish-crate:
215+
name: Publish to crates.io
216+
needs: create-release
217+
runs-on: ubuntu-latest
218+
219+
steps:
220+
- uses: actions/checkout@v4
221+
with:
222+
ref: ${{ github.ref }}
223+
224+
- name: Install Rust
225+
uses: dtolnay/rust-toolchain@stable
226+
227+
- name: Verify version matches tag
228+
run: |
229+
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
230+
CARGO_VERSION=$(grep "^version" Cargo.toml | head -1 | cut -d'"' -f2)
231+
if [ "$TAG_VERSION" != "$CARGO_VERSION" ]; then
232+
echo "Error: Tag version ($TAG_VERSION) doesn't match Cargo.toml version ($CARGO_VERSION)"
233+
exit 1
234+
fi
235+
echo "CARGO_VERSION=$CARGO_VERSION" >> $GITHUB_ENV
236+
237+
- name: Publish to crates.io
238+
run: |
239+
# Try to publish, but don't fail if the version already exists
240+
cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} --verbose || {
241+
EXIT_CODE=$?
242+
# Check if it failed because the version already exists
243+
cargo search sql-schema --limit 1 | grep -q "sql-schema = \"$CARGO_VERSION\"" && {
244+
echo "Version $CARGO_VERSION already published on crates.io, skipping..."
245+
exit 0
246+
}
247+
# If it failed for another reason, exit with the original error code
248+
exit $EXIT_CODE
249+
}
250+
env:
251+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

β€Žcliff.tomlβ€Ž

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# git-cliff ~ configuration file
2+
# https://git-cliff.org/docs/configuration
3+
4+
5+
[changelog]
6+
# A Tera template to be rendered for each release in the changelog.
7+
# See https://keats.github.io/tera/docs/#introduction
8+
body = """
9+
{% if version %}\
10+
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
11+
{% else %}\
12+
## [unreleased]
13+
{% endif %}\
14+
{% for group, commits in commits | group_by(attribute="group") %}
15+
### {{ group | striptags | trim | upper_first }}
16+
{% for commit in commits %}
17+
- {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
18+
{% if commit.breaking %}[**breaking**] {% endif %}\
19+
{{ commit.message | upper_first }}\
20+
{% endfor %}
21+
{% endfor %}
22+
"""
23+
# Remove leading and trailing whitespaces from the changelog's body.
24+
trim = true
25+
# Render body even when there are no releases to process.
26+
render_always = true
27+
# An array of regex based postprocessors to modify the changelog.
28+
postprocessors = [
29+
# Replace the placeholder <REPO> with a URL.
30+
#{ pattern = '<REPO>', replace = "https://github.com/orhun/git-cliff" },
31+
]
32+
# render body even when there are no releases to process
33+
# render_always = true
34+
# output file path
35+
# output = "test.md"
36+
37+
[git]
38+
# Parse commits according to the conventional commits specification.
39+
# See https://www.conventionalcommits.org
40+
conventional_commits = true
41+
# Exclude commits that do not match the conventional commits specification.
42+
filter_unconventional = true
43+
# Require all commits to be conventional.
44+
# Takes precedence over filter_unconventional.
45+
require_conventional = false
46+
# Split commits on newlines, treating each line as an individual commit.
47+
split_commits = false
48+
# An array of regex based parsers to modify commit messages prior to further processing.
49+
commit_preprocessors = [
50+
# Replace issue numbers with link templates to be updated in `changelog.postprocessors`.
51+
#{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))"},
52+
# Check spelling of the commit message using https://github.com/crate-ci/typos.
53+
# If the spelling is incorrect, it will be fixed automatically.
54+
#{ pattern = '.*', replace_command = 'typos --write-changes -' },
55+
]
56+
# Prevent commits that are breaking from being excluded by commit parsers.
57+
protect_breaking_commits = false
58+
# An array of regex based parsers for extracting data from the commit message.
59+
# Assigns commits to groups.
60+
# Optionally sets the commit's scope and can decide to exclude commits from further processing.
61+
commit_parsers = [
62+
{ message = "^feat", group = "<!-- 0 -->πŸš€ Features" },
63+
{ message = "^fix", group = "<!-- 1 -->πŸ› Bug Fixes" },
64+
{ message = "^doc", group = "<!-- 3 -->πŸ“š Documentation" },
65+
{ message = "^perf", group = "<!-- 4 -->⚑ Performance" },
66+
{ message = "^refactor", group = "<!-- 2 -->🚜 Refactor" },
67+
{ message = "^style", group = "<!-- 5 -->🎨 Styling" },
68+
{ message = "^test", group = "<!-- 6 -->πŸ§ͺ Testing" },
69+
{ message = "^chore\\(release\\): prepare for", skip = true },
70+
{ message = "^chore\\(deps.*\\)", skip = true },
71+
{ message = "^chore\\(pr\\)", skip = true },
72+
{ message = "^chore\\(pull\\)", skip = true },
73+
{ message = "^chore\\(github\\)", skip = true },
74+
{ message = "^chore|^ci", group = "<!-- 7 -->βš™οΈ Miscellaneous Tasks" },
75+
{ body = ".*security", group = "<!-- 8 -->πŸ›‘οΈ Security" },
76+
{ message = "^revert", group = "<!-- 9 -->◀️ Revert" },
77+
{ message = ".*", group = "<!-- 10 -->πŸ’Ό Other" },
78+
]
79+
# Exclude commits that are not matched by any commit parser.
80+
filter_commits = false
81+
# An array of link parsers for extracting external references, and turning them into URLs, using regex.
82+
link_parsers = []
83+
# Include only the tags that belong to the current branch.
84+
use_branch_tags = false
85+
# Order releases topologically instead of chronologically.
86+
topo_order = false
87+
# Order releases topologically instead of chronologically.
88+
topo_order_commits = true
89+
# Order of commits in each group/release within the changelog.
90+
# Allowed values: newest, oldest
91+
sort_commits = "oldest"
92+
# Process submodules commits
93+
recurse_submodules = false

0 commit comments

Comments
Β (0)