name: CI on: push: branches: - "**" pull_request: branches: - main env: CARGO_TERM_COLOR: always RUSTFLAGS: "-D warnings" # Cancel in-progress runs for the same branch/PR concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: # --------------------------------------------------------------------------- # Stage 1: Code quality checks (run in parallel) # --------------------------------------------------------------------------- fmt: name: Format runs-on: docker container: image: rust:1.89-bookworm steps: - name: Checkout run: | git init git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git" git fetch --depth=1 origin "${GITHUB_SHA}" git checkout FETCH_HEAD - run: rustup component add rustfmt - run: cargo fmt --check - name: Install dx CLI run: cargo install dioxus-cli@0.7.3 --locked - name: RSX format check run: dx fmt --check clippy: name: Clippy runs-on: docker container: image: rust:1.89-bookworm steps: - name: Checkout run: | git init git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git" git fetch --depth=1 origin "${GITHUB_SHA}" git checkout FETCH_HEAD - run: rustup component add clippy # Lint both feature sets independently - name: Clippy (server) run: cargo clippy --features server --no-default-features -- -D warnings - name: Clippy (web) run: cargo clippy --features web --no-default-features -- -D warnings audit: name: Security Audit runs-on: docker container: image: rust:1.89-bookworm steps: - name: Checkout run: | git init git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git" git fetch --depth=1 origin "${GITHUB_SHA}" git checkout FETCH_HEAD - run: cargo install cargo-audit - run: cargo audit # --------------------------------------------------------------------------- # Stage 2: Tests (only after all quality checks pass) # --------------------------------------------------------------------------- test: name: Tests runs-on: docker needs: [fmt, clippy, audit] container: image: rust:1.89-bookworm steps: - name: Checkout run: | git init git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git" git fetch --depth=1 origin "${GITHUB_SHA}" git checkout FETCH_HEAD - name: Run tests (server) run: cargo test --features server --no-default-features - name: Run tests (web) run: cargo test --features web --no-default-features # --------------------------------------------------------------------------- # Stage 3: Build Docker image and push to registry # Only on main and release/* branches # --------------------------------------------------------------------------- build-and-push: name: Build & Push Image runs-on: docker needs: [test] if: >- github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) steps: - name: Checkout run: | git init git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git" git fetch --depth=1 origin "${GITHUB_SHA}" git checkout FETCH_HEAD - name: Determine image tag id: tag run: | BRANCH="${GITHUB_REF#refs/heads/}" # Replace / with - for valid Docker tags (e.g. release/1.0 -> release-1.0) BRANCH_SAFE=$(echo "$BRANCH" | tr '/' '-') SHA=$(echo "$GITHUB_SHA" | head -c 8) echo "tag=${BRANCH_SAFE}-${SHA}" >> "$GITHUB_OUTPUT" - name: Log in to container registry run: >- echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login https://registry.meghsakha.com -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin - name: Build Docker image run: >- docker build -t registry.meghsakha.com/certifai/dashboard:${{ steps.tag.outputs.tag }} -t registry.meghsakha.com/certifai/dashboard:latest . - name: Push Docker image run: | docker push registry.meghsakha.com/certifai/dashboard:${{ steps.tag.outputs.tag }} docker push registry.meghsakha.com/certifai/dashboard:latest # --------------------------------------------------------------------------- # Stage 3b: Generate changelog from conventional commits # Only on main and release/* branches # --------------------------------------------------------------------------- changelog: name: Changelog runs-on: docker needs: [test] if: >- github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) container: image: rust:1.89-bookworm steps: - name: Checkout (full history) run: | git clone "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git" . git checkout "${GITHUB_SHA}" - name: Install git-cliff run: cargo install git-cliff --locked - name: Generate changelog run: git cliff --output CHANGELOG.md - name: Upload changelog artifact uses: actions/upload-artifact@v4 with: name: changelog path: CHANGELOG.md