@@ -3,37 +3,25 @@ name: CI/CD
33on :
44 push :
55 branches :
6+ - main
67 - ' **'
8+ pull_request :
9+ branches :
10+ - main
11+ workflow_dispatch :
712
813env :
9- BINARY_NAME : modrinth-api
10- BUILD_WINDOWS : 1
11- BUILD_LINUX : 1
14+ CARGO_TERM_COLOR : always
1215
1316jobs :
14- build :
15- name : Build (Debug/Release based on ref )
16- runs-on : ubuntu-latest
17+ test_and_lint :
18+ name : Test & Lint (${{ matrix.os }} )
19+ runs-on : ${{ matrix.os }}
1720 strategy :
1821 fail-fast : false
1922 matrix :
20- include :
21- - target : x86_64-pc-windows-gnu
22- os : windows-latest
23- rust : stable
24- build_os : windows
25- arch : x64
26- - target : i686-pc-windows-gnu
27- os : windows-latest
28- rust : stable
29- build_os : windows
30- arch : x86
31- - target : x86_64-unknown-linux-gnu
32- os : ubuntu-latest
33- rust : stable
34- build_os : linux
35- arch : x64
36-
23+ os : [ ubuntu-latest, windows-latest, macos-latest ]
24+ rust : [ stable ]
3725 steps :
3826 - name : Checkout code
3927 uses : actions/checkout@v4
@@ -42,65 +30,28 @@ jobs:
4230 uses : actions-rust-lang/setup-rust-toolchain@v1
4331 with :
4432 toolchain : ${{ matrix.rust }}
45- target : ${{ matrix.target }}
46- components : rustfmt
47- override : true
33+ components : rustfmt, clippy
4834
49- - name : Install MinGW-w64 toolchain
50- if : matrix.build_os == 'windows'
51- run : |
52- sudo apt-get update
53- sudo apt-get install -y --no-install-recommends mingw-w64
35+ - name : Check formatting
36+ run : cargo fmt --all -- --check
5437
55- - name : Determine build type
56- id : build_type
57- run : |
58- if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
59- echo "build_mode=release" >> $GITHUB_OUTPUT
60- else
61- echo "build_mode=debug" >> $GITHUB_OUTPUT
62- fi
38+ - name : Clippy Lints
39+ run : cargo clippy --all-targets --all-features -- -D warnings
6340
64- - name : Build project (${{ matrix.build_os }} - ${{ matrix.arch }})
65- if : |
66- (matrix.build_os == 'windows' && env.BUILD_WINDOWS == '1') ||
67- (matrix.build_os == 'linux' && env.BUILD_LINUX == '1')
68- run : cargo build ${{ steps.build_type.outputs.build_mode == 'release' && '--release' || '' }} --target ${{ matrix.target }}
69-
70- - name : Create artifacts directory
71- shell : bash
72- run : mkdir -p artifacts
73-
74- - name : Copy binary to artifacts (${{ matrix.build_os }} - ${{ matrix.arch }})
75- if : |
76- (matrix.build_os == 'windows' && env.BUILD_WINDOWS == '1') ||
77- (matrix.build_os == 'linux' && env.BUILD_LINUX == '1')
78- shell : bash
79- run : |
80- BUILD_MODE="${{ steps.build_type.outputs.build_mode }}"
81- TARGET_DIR="target/${{ matrix.target }}/${BUILD_MODE}"
82- SOURCE_EXE="${TARGET_DIR}/${{ env.BINARY_NAME }}.exe"
83- SOURCE_BIN="${TARGET_DIR}/${{ env.BINARY_NAME }}"
84-
85- if [[ "${{ matrix.build_os }}" == "windows" ]]; then
86- cp "${SOURCE_EXE}" "artifacts/${{ env.BINARY_NAME }}-${{ matrix.target }}.exe"
87- else
88- cp "${SOURCE_BIN}" "artifacts/${{ env.BINARY_NAME }}-${{ matrix.target }}"
89- fi
41+ - name : Run tests
42+ run : cargo test --all-targets --all-features --verbose
9043
91- - name : Upload Build Artifacts (${{ steps.build_type.outputs.build_mode }})
92- uses : actions/upload-artifact@v4
93- with :
94- name : ${{ env.BINARY_NAME }}-${{ matrix.build_os }}-${{ matrix.arch }}-${{ steps.build_type.outputs.build_mode }}
95- path : artifacts/*
96- if-no-files-found : error
44+ - name : Build documentation (as a check)
45+ run : cargo doc --no-deps --all-features
9746
98- check_version :
99- name : Check Version
47+ check_version_for_release :
48+ name : Check Version for Release
10049 runs-on : ubuntu-latest
10150 outputs :
102- should_release : ${{ steps.check_version_logic .outputs.should_release }}
51+ should_release : ${{ steps.check_logic .outputs.should_release }}
10352 current_version : ${{ steps.get_version.outputs.current_version }}
53+ is_prerelease : ${{ steps.check_logic.outputs.is_prerelease }}
54+ tag_name : ${{ steps.check_logic.outputs.tag_name }}
10455 steps :
10556 - name : Checkout code
10657 uses : actions/checkout@v4
@@ -114,147 +65,69 @@ jobs:
11465 echo "current_version=$VERSION" >> $GITHUB_OUTPUT
11566 echo "Current Cargo.toml version: $VERSION"
11667
117- - name : Get latest release tag
118- id : get_latest_tag
119- run : |
120- LATEST_TAG=$(git tag --sort=-v:refname | head -n 1)
121- echo "latest_tag=$LATEST_TAG" >> $GITHUB_OUTPUT
122- echo "Latest Git tag: $LATEST_TAG"
123-
124- - name : Check if version has changed
125- id : check_version_logic
68+ - name : Determine if release is needed and if it's a prerelease
69+ id : check_logic
12670 run : |
12771 CURRENT_VERSION="${{ steps.get_version.outputs.current_version }}"
128- LATEST_TAG="${{ steps.get_latest_tag.outputs.latest_tag } }"
72+ TAG_NAME="v${CURRENT_VERSION }"
12973 SHOULD_RELEASE="false"
74+ IS_PRERELEASE="false"
13075
131- if [[ -n "$LATEST_TAG" ]]; then
132- LATEST_VERSION_FROM_TAG="${LATEST_TAG#v}" # Удаляем 'v' если есть
133- if [[ "$CURRENT_VERSION" != "$LATEST_VERSION_FROM_TAG" ]]; then
134- SHOULD_RELEASE="true"
135- echo "Version changed: $LATEST_VERSION_FROM_TAG -> $CURRENT_VERSION. Should release."
136- else
137- echo "Version $CURRENT_VERSION is the same as latest tag $LATEST_TAG. No release needed."
138- fi
76+ if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then
77+ echo "Tag $TAG_NAME already exists. No release needed for version $CURRENT_VERSION."
13978 else
79+ echo "Tag $TAG_NAME does not exist for version $CURRENT_VERSION. A release should be created."
14080 SHOULD_RELEASE="true"
141- echo "No previous tags found. Should release version $CURRENT_VERSION."
14281 fi
143- echo "should_release=$SHOULD_RELEASE" >> $GITHUB_OUTPUT
14482
145- build_release :
146- name : Build Release Binaries
147- needs : [ check_version ]
148- if : needs.check_version.outputs.should_release == 'true' && github.ref_name == 'main'
149- runs-on : ubuntu-latest
150- strategy :
151- fail-fast : false
152- matrix :
153- include :
154- - target : x86_64-pc-windows-gnu
155- os : windows-latest
156- rust : stable
157- build_os : windows
158- arch : x64
159- - target : i686-pc-windows-gnu
160- os : windows-latest
161- rust : stable
162- build_os : windows
163- arch : x86
164- - target : x86_64-unknown-linux-gnu
165- os : ubuntu-latest
166- rust : stable
167- build_os : linux
168- arch : x64
169- steps :
170- - name : Checkout code
171- uses : actions/checkout@v4
172-
173- - name : Install Rust toolchain
174- uses : actions-rust-lang/setup-rust-toolchain@v1
175- with :
176- toolchain : ${{ matrix.rust }}
177- target : ${{ matrix.target }}
178- components : rustfmt
179- override : true
180-
181- - name : Install MinGW-w64 toolchain
182- if : matrix.build_os == 'windows'
183- run : |
184- sudo apt-get update
185- sudo apt-get install -y --no-install-recommends mingw-w64
186-
187- - name : Build Release Binaries (${{ matrix.build_os }} - ${{ matrix.arch }})
188- run : cargo build --release --target ${{ matrix.target }}
189-
190- - name : Create release package directory
191- shell : bash
192- run : mkdir -p release-package
193-
194- - name : Copy release binary to package (${{ matrix.build_os }} - ${{ matrix.arch }})
195- shell : bash
196- run : |
197- TARGET_DIR="target/${{ matrix.target }}/release"
198- DEST_DIR="release-package" # Всегда одна и та же папка назначения для артефакта
199- SOURCE_EXE="${TARGET_DIR}/${{ env.BINARY_NAME }}.exe"
200- SOURCE_BIN="${TARGET_DIR}/${{ env.BINARY_NAME }}"
201-
202- if [[ "${{ matrix.build_os }}" == "windows" ]]; then
203- cp "${SOURCE_EXE}" "${DEST_DIR}/${{ env.BINARY_NAME }}-${{ matrix.target }}.exe"
83+ if echo "$CURRENT_VERSION" | grep -q '-'; then
84+ IS_PRERELEASE="true"
85+ echo "Version $CURRENT_VERSION is a pre-release."
20486 else
205- cp "${SOURCE_BIN}" "${DEST_DIR}/${{ env.BINARY_NAME }}-${{ matrix.target }} "
87+ echo "Version $CURRENT_VERSION is a full release. "
20688 fi
20789
208- - name : Upload Release Build Artifact
209- uses : actions/upload-artifact@v4
210- with :
211- name : release-asset-${{ matrix.target }}
212- path : release-package/*
213- if-no-files-found : error
90+ echo "should_release=$SHOULD_RELEASE" >> $GITHUB_OUTPUT
91+ echo "is_prerelease=$IS_PRERELEASE" >> $GITHUB_OUTPUT
92+ echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
21493
215- publish_release :
216- name : Publish GitHub Release
217- needs : [ check_version, build_release ]
218- if : needs.check_version.outputs.should_release == 'true' && github.ref_name == 'main'
94+ publish_crate_release :
95+ name : Create Tag and Publish GitHub Release
96+ if : github.ref == 'refs/heads/main' && needs.check_version_for_release.outputs.should_release == 'true'
97+ needs : [ test_and_lint, check_version_for_release ]
98+ runs-on : ubuntu-latest
21999 permissions :
220100 contents : write
221- pull-requests : write
222- runs-on : ubuntu-latest
223101 steps :
224- - name : Checkout code (for release-drafter)
102+ - name : Checkout code
225103 uses : actions/checkout@v4
226- with :
227- fetch-depth : 0
228-
229- - name : Download all release assets
230- uses : actions/download-artifact@v4
231- with :
232- path : all-release-assets
233104
234- - name : List downloaded files (for debugging)
105+ - name : Configure Git
235106 run : |
236- echo "Downloaded artifacts will be in subdirectories under all-release-assets/ "
237- ls -R all-release-assets
107+ git config --global user.name "github-actions[bot] "
108+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
238109
239- - name : Create Release Notes
240- id : release_notes
241- uses : release-drafter/release-drafter@v6
110+ - name : Create and Push Git Tag
242111 env :
243- GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
244- with :
245- name : Release v${{ needs.check_version.outputs.current_version }}
246- tag : v${{ needs.check_version.outputs.current_version }}
112+ TAG_NAME : ${{ needs.check_version_for_release.outputs.tag_name }}
113+ run : |
114+ echo "Creating and pushing tag $TAG_NAME"
115+ git tag "$TAG_NAME" -m "Release $TAG_NAME"
116+ git push origin "$TAG_NAME"
247117
248- - name : Upload Release Assets to GitHub Release
249- uses : softprops/action-gh-release@v2
118+ - name : Create GitHub Release
250119 env :
251- GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
252- with :
253- tag_name : v${{ needs.check_version.outputs.current_version }}
254- name : Release v${{ needs.check_version.outputs.current_version }}
255- body : ${{ steps.release_notes.outputs.body }}
256- files : |
257- all-release-assets/release-asset-*/*
258- fail_on_unmatched_files : true
259- draft : false
260- prerelease : false
120+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
121+ TAG_NAME : ${{ needs.check_version_for_release.outputs.tag_name }}
122+ IS_PRERELEASE : ${{ needs.check_version_for_release.outputs.is_prerelease }}
123+ run : |
124+ PRERELEASE_OPTION=""
125+ if [[ "$IS_PRERELEASE" == "true" ]]; then
126+ PRERELEASE_OPTION="--prerelease"
127+ fi
128+
129+ echo "Creating GitHub release for tag $TAG_NAME"
130+ gh release create "$TAG_NAME" \
131+ --title "Release $TAG_NAME" \
132+ --generate-notes \
133+ $PRERELEASE_OPTION
0 commit comments