From 87078738c797905ee32952ef8aae9c812487ad01 Mon Sep 17 00:00:00 2001 From: nixxoq Date: Thu, 29 May 2025 18:50:45 +0300 Subject: [PATCH] feat(ci/cd): testing new ci/cd --- .github/workflows/rust.yml | 265 ++++++++++--------------------------- 1 file changed, 69 insertions(+), 196 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 659a01f..9de7fd0 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -3,37 +3,25 @@ name: CI/CD on: push: branches: + - main - '**' + pull_request: + branches: + - main + workflow_dispatch: env: - BINARY_NAME: modrinth-api - BUILD_WINDOWS: 1 - BUILD_LINUX: 1 + CARGO_TERM_COLOR: always jobs: - build: - name: Build (Debug/Release based on ref) - runs-on: ubuntu-latest + test_and_lint: + name: Test & Lint (${{ matrix.os }}) + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - include: - - target: x86_64-pc-windows-gnu - os: windows-latest - rust: stable - build_os: windows - arch: x64 - - target: i686-pc-windows-gnu - os: windows-latest - rust: stable - build_os: windows - arch: x86 - - target: x86_64-unknown-linux-gnu - os: ubuntu-latest - rust: stable - build_os: linux - arch: x64 - + os: [ ubuntu-latest, windows-latest, macos-latest ] + rust: [ stable ] steps: - name: Checkout code uses: actions/checkout@v4 @@ -42,65 +30,28 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - components: rustfmt - override: true + components: rustfmt, clippy - - name: Install MinGW-w64 toolchain - if: matrix.build_os == 'windows' - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends mingw-w64 + - name: Check formatting + run: cargo fmt --all -- --check - - name: Determine build type - id: build_type - run: | - if [[ "${GITHUB_REF}" == refs/tags/* ]]; then - echo "build_mode=release" >> $GITHUB_OUTPUT - else - echo "build_mode=debug" >> $GITHUB_OUTPUT - fi + - name: Clippy Lints + run: cargo clippy --all-targets --all-features -- -D warnings - - name: Build project (${{ matrix.build_os }} - ${{ matrix.arch }}) - if: | - (matrix.build_os == 'windows' && env.BUILD_WINDOWS == '1') || - (matrix.build_os == 'linux' && env.BUILD_LINUX == '1') - run: cargo build ${{ steps.build_type.outputs.build_mode == 'release' && '--release' || '' }} --target ${{ matrix.target }} - - - name: Create artifacts directory - shell: bash - run: mkdir -p artifacts - - - name: Copy binary to artifacts (${{ matrix.build_os }} - ${{ matrix.arch }}) - if: | - (matrix.build_os == 'windows' && env.BUILD_WINDOWS == '1') || - (matrix.build_os == 'linux' && env.BUILD_LINUX == '1') - shell: bash - run: | - BUILD_MODE="${{ steps.build_type.outputs.build_mode }}" - TARGET_DIR="target/${{ matrix.target }}/${BUILD_MODE}" - SOURCE_EXE="${TARGET_DIR}/${{ env.BINARY_NAME }}.exe" - SOURCE_BIN="${TARGET_DIR}/${{ env.BINARY_NAME }}" - - if [[ "${{ matrix.build_os }}" == "windows" ]]; then - cp "${SOURCE_EXE}" "artifacts/${{ env.BINARY_NAME }}-${{ matrix.target }}.exe" - else - cp "${SOURCE_BIN}" "artifacts/${{ env.BINARY_NAME }}-${{ matrix.target }}" - fi + - name: Run tests + run: cargo test --all-targets --all-features --verbose - - name: Upload Build Artifacts (${{ steps.build_type.outputs.build_mode }}) - uses: actions/upload-artifact@v4 - with: - name: ${{ env.BINARY_NAME }}-${{ matrix.build_os }}-${{ matrix.arch }}-${{ steps.build_type.outputs.build_mode }} - path: artifacts/* - if-no-files-found: error + - name: Build documentation (as a check) + run: cargo doc --no-deps --all-features - check_version: - name: Check Version + check_version_for_release: + name: Check Version for Release runs-on: ubuntu-latest outputs: - should_release: ${{ steps.check_version_logic.outputs.should_release }} + should_release: ${{ steps.check_logic.outputs.should_release }} current_version: ${{ steps.get_version.outputs.current_version }} + is_prerelease: ${{ steps.check_logic.outputs.is_prerelease }} + tag_name: ${{ steps.check_logic.outputs.tag_name }} steps: - name: Checkout code uses: actions/checkout@v4 @@ -114,147 +65,69 @@ jobs: echo "current_version=$VERSION" >> $GITHUB_OUTPUT echo "Current Cargo.toml version: $VERSION" - - name: Get latest release tag - id: get_latest_tag - run: | - LATEST_TAG=$(git tag --sort=-v:refname | head -n 1) - echo "latest_tag=$LATEST_TAG" >> $GITHUB_OUTPUT - echo "Latest Git tag: $LATEST_TAG" - - - name: Check if version has changed - id: check_version_logic + - name: Determine if release is needed and if it's a prerelease + id: check_logic run: | CURRENT_VERSION="${{ steps.get_version.outputs.current_version }}" - LATEST_TAG="${{ steps.get_latest_tag.outputs.latest_tag }}" + TAG_NAME="v${CURRENT_VERSION}" SHOULD_RELEASE="false" + IS_PRERELEASE="false" - if [[ -n "$LATEST_TAG" ]]; then - LATEST_VERSION_FROM_TAG="${LATEST_TAG#v}" # Удаляем 'v' если есть - if [[ "$CURRENT_VERSION" != "$LATEST_VERSION_FROM_TAG" ]]; then - SHOULD_RELEASE="true" - echo "Version changed: $LATEST_VERSION_FROM_TAG -> $CURRENT_VERSION. Should release." - else - echo "Version $CURRENT_VERSION is the same as latest tag $LATEST_TAG. No release needed." - fi + if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then + echo "Tag $TAG_NAME already exists. No release needed for version $CURRENT_VERSION." else + echo "Tag $TAG_NAME does not exist for version $CURRENT_VERSION. A release should be created." SHOULD_RELEASE="true" - echo "No previous tags found. Should release version $CURRENT_VERSION." fi - echo "should_release=$SHOULD_RELEASE" >> $GITHUB_OUTPUT - build_release: - name: Build Release Binaries - needs: [ check_version ] - if: needs.check_version.outputs.should_release == 'true' && github.ref_name == 'main' - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - include: - - target: x86_64-pc-windows-gnu - os: windows-latest - rust: stable - build_os: windows - arch: x64 - - target: i686-pc-windows-gnu - os: windows-latest - rust: stable - build_os: windows - arch: x86 - - target: x86_64-unknown-linux-gnu - os: ubuntu-latest - rust: stable - build_os: linux - arch: x64 - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install Rust toolchain - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - components: rustfmt - override: true - - - name: Install MinGW-w64 toolchain - if: matrix.build_os == 'windows' - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends mingw-w64 - - - name: Build Release Binaries (${{ matrix.build_os }} - ${{ matrix.arch }}) - run: cargo build --release --target ${{ matrix.target }} - - - name: Create release package directory - shell: bash - run: mkdir -p release-package - - - name: Copy release binary to package (${{ matrix.build_os }} - ${{ matrix.arch }}) - shell: bash - run: | - TARGET_DIR="target/${{ matrix.target }}/release" - DEST_DIR="release-package" # Всегда одна и та же папка назначения для артефакта - SOURCE_EXE="${TARGET_DIR}/${{ env.BINARY_NAME }}.exe" - SOURCE_BIN="${TARGET_DIR}/${{ env.BINARY_NAME }}" - - if [[ "${{ matrix.build_os }}" == "windows" ]]; then - cp "${SOURCE_EXE}" "${DEST_DIR}/${{ env.BINARY_NAME }}-${{ matrix.target }}.exe" + if echo "$CURRENT_VERSION" | grep -q '-'; then + IS_PRERELEASE="true" + echo "Version $CURRENT_VERSION is a pre-release." else - cp "${SOURCE_BIN}" "${DEST_DIR}/${{ env.BINARY_NAME }}-${{ matrix.target }}" + echo "Version $CURRENT_VERSION is a full release." fi - - name: Upload Release Build Artifact - uses: actions/upload-artifact@v4 - with: - name: release-asset-${{ matrix.target }} - path: release-package/* - if-no-files-found: error + echo "should_release=$SHOULD_RELEASE" >> $GITHUB_OUTPUT + echo "is_prerelease=$IS_PRERELEASE" >> $GITHUB_OUTPUT + echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT - publish_release: - name: Publish GitHub Release - needs: [ check_version, build_release ] - if: needs.check_version.outputs.should_release == 'true' && github.ref_name == 'main' + publish_crate_release: + name: Create Tag and Publish GitHub Release + if: github.ref == 'refs/heads/main' && needs.check_version_for_release.outputs.should_release == 'true' + needs: [ test_and_lint, check_version_for_release ] + runs-on: ubuntu-latest permissions: contents: write - pull-requests: write - runs-on: ubuntu-latest steps: - - name: Checkout code (for release-drafter) + - name: Checkout code uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Download all release assets - uses: actions/download-artifact@v4 - with: - path: all-release-assets - - name: List downloaded files (for debugging) + - name: Configure Git run: | - echo "Downloaded artifacts will be in subdirectories under all-release-assets/" - ls -R all-release-assets + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" - - name: Create Release Notes - id: release_notes - uses: release-drafter/release-drafter@v6 + - name: Create and Push Git Tag env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - name: Release v${{ needs.check_version.outputs.current_version }} - tag: v${{ needs.check_version.outputs.current_version }} + TAG_NAME: ${{ needs.check_version_for_release.outputs.tag_name }} + run: | + echo "Creating and pushing tag $TAG_NAME" + git tag "$TAG_NAME" -m "Release $TAG_NAME" + git push origin "$TAG_NAME" - - name: Upload Release Assets to GitHub Release - uses: softprops/action-gh-release@v2 + - name: Create GitHub Release env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: v${{ needs.check_version.outputs.current_version }} - name: Release v${{ needs.check_version.outputs.current_version }} - body: ${{ steps.release_notes.outputs.body }} - files: | - all-release-assets/release-asset-*/* - fail_on_unmatched_files: true - draft: false - prerelease: false \ No newline at end of file + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG_NAME: ${{ needs.check_version_for_release.outputs.tag_name }} + IS_PRERELEASE: ${{ needs.check_version_for_release.outputs.is_prerelease }} + run: | + PRERELEASE_OPTION="" + if [[ "$IS_PRERELEASE" == "true" ]]; then + PRERELEASE_OPTION="--prerelease" + fi + + echo "Creating GitHub release for tag $TAG_NAME" + gh release create "$TAG_NAME" \ + --title "Release $TAG_NAME" \ + --generate-notes \ + $PRERELEASE_OPTION