From bd2e0b4394a61717ac78009c8a07a8c4854cabc0 Mon Sep 17 00:00:00 2001 From: oopsbagel Date: Thu, 5 Jun 2025 16:46:19 -0700 Subject: [PATCH] ci: release from actions, only test changed files This commit introduces release automation triggered by button clicks in Github Actions, guarded by a check on whether all the Cargo.toml files contain the same version string. On PRs, changes to documentation no longer trigger code tests. Similarly, changes to code that don't update documentation do not trigger documentation tests. Changes that fail at the `cargo check` stage abort early to prevent lengthy CI builds of the installer and firmware. Commits on the `main` branch always run the full test suite regardless of what changed. Releases also run the full check, test, build and publish suite. --- .github/workflows/check-and-test.yml | 54 ------ .../workflows/{build-release.yml => main.yml} | 162 +++++++++++++++++- .github/workflows/mdbook.yaml | 47 ----- .github/workflows/release.yml | 48 ++++++ 4 files changed, 207 insertions(+), 104 deletions(-) delete mode 100644 .github/workflows/check-and-test.yml rename .github/workflows/{build-release.yml => main.yml} (53%) delete mode 100644 .github/workflows/mdbook.yaml create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/check-and-test.yml b/.github/workflows/check-and-test.yml deleted file mode 100644 index 1f0d0c4..0000000 --- a/.github/workflows/check-and-test.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Check and Test - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -env: - CARGO_TERM_COLOR: always - NO_FIRMWARE_BIN: true - -jobs: - check_and_test: - strategy: - matrix: - device: - - name: tplink - - name: orbic - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Check - run: | - pushd bin/web - npm install - npm run build - popd - cargo check --verbose --no-default-features --features=${{ matrix.device.name }} - - name: Run tests - run: | - pushd bin/web - npm install - npm run build - popd - cargo test --verbose --no-default-features --features=${{ matrix.device.name }} - - name: Run clippy - run: cargo clippy --verbose --no-default-features --features=${{ matrix.device.name }} - - windows_installer_check_and_test: - runs-on: windows-latest - steps: - - uses: actions/checkout@v3 - - name: cargo check - shell: bash - run: | - cd installer - cargo check --verbose - - name: cargo test - shell: bash - run: | - cd installer - cargo test --verbose --no-default-features --features=${{ matrix.device.name }} diff --git a/.github/workflows/build-release.yml b/.github/workflows/main.yml similarity index 53% rename from .github/workflows/build-release.yml rename to .github/workflows/main.yml index 4c3ba5d..d93d1d4 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/main.yml @@ -1,10 +1,9 @@ -name: Build Release +name: Check, test, build release zip, publish docs on: push: - branches: [main, "release-*"] pull_request: - branches: ["main"] + workflow_call: env: CARGO_TERM_COLOR: always @@ -13,7 +12,139 @@ env: FILE_RAYHUNTER_DAEMON_TPLINK: ../../rayhunter-daemon-tplink/rayhunter-daemon jobs: + files_changed: + name: Detect file changes + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + code_changed: ${{ steps.files_changed.outputs.code_count }} + daemon_changed: ${{ steps.files_changed.outputs.daemon_count }} + docs_changed: ${{ steps.files_changed.outputs.docs_count }} + installer_changed: ${{ steps.files_changed.outputs.installer_count }} + rootshell_changed: ${{ steps.files_changed.outputs.rootshell_count }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: detect file changes + id: files_changed + run: | + lcommit=${{ github.event.pull_request.base.sha || 'origin/main' }} + if [ ${{ github.ref }} = 'refs/heads/main' ] + then + echo "building everything" + echo code_count=forced >> "$GITHUB_OUTPUT" + echo daemon_count=forced >> "$GITHUB_OUTPUT" + echo docs_count=forced >> "$GITHUB_OUTPUT" + echo installer_count=forced >> "$GITHUB_OUTPUT" + echo rootshell_count=forced >> "$GITHUB_OUTPUT" + else + echo "code_count=$(git diff --name-only $lcommit...HEAD | grep -e ^bin -e ^installer -e ^lib -e ^rootshell -e ^telcom-parser | wc -l)" >> "$GITHUB_OUTPUT" + echo "daemon_count=$(git diff --name-only $lcommit...HEAD | grep -e ^bin -e ^lib -e ^telcom-parser | wc -l)" >> "$GITHUB_OUTPUT" + echo "docs_count=$(git diff --name-only $lcommit...HEAD | grep -e ^book.toml -e ^doc | wc -l)" >> "$GITHUB_OUTPUT" + echo "installer_count=$(git diff --name-only $lcommit...HEAD | grep -e ^installer | wc -l)" >> "$GITHUB_OUTPUT" + echo "rootshell_count=$(git diff --name-only $lcommit...HEAD | grep -e ^rootshell | wc -l)" >> "$GITHUB_OUTPUT" + fi + + mdbook_test: + name: Test mdBook Documentation builds + needs: files_changed + if: needs.files_changed.outputs.docs_changed != '0' + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + - name: Install mdBook + run: | + cargo install mdbook --no-default-features --features search --vers "^0.4" --locked + - name: Test mdBook + run: mdbook test + + mdbook_publish: + name: Publish mdBook to Github Pages + needs: mdbook_test + if: ${{ github.event_name != 'pull_request' }} + permissions: + pages: write + contents: write + id-token: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install mdBook + run: | + cargo install mdbook --no-default-features --features search --vers "^0.4" --locked + + - name: Build mdBook + run: mdbook build + + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: book + - name: Deploy to Github Pages + uses: actions/deploy-pages@v4 + + check_and_test: + needs: files_changed + if: needs.files_changed.outputs.code_changed != '0' + strategy: + matrix: + device: + - name: tplink + - name: orbic + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + - name: Check formatting + run: cargo fmt --all --check + - name: Check + run: | + pushd bin/web + npm install + npm run build + popd + NO_FIRMWARE_BIN=true cargo check --verbose --no-default-features --features=${{ matrix.device.name }} + - name: Run tests + run: | + NO_FIRMWARE_BIN=true cargo test --verbose --no-default-features --features=${{ matrix.device.name }} + - name: Run clippy + run: | + NO_FIRMWARE_BIN=true cargo clippy --verbose --no-default-features --features=${{ matrix.device.name }} + + windows_installer_check_and_test: + needs: files_changed + if: needs.files_changed.outputs.installer_changed != '0' + runs-on: windows-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + - name: cargo check + shell: bash + run: | + cd installer + NO_FIRMWARE_BIN=true cargo check --verbose + - name: cargo test + shell: bash + run: | + cd installer + NO_FIRMWARE_BIN=true cargo test --verbose --no-default-features + build_rayhunter_check: + if: needs.files_changed.outputs.daemon_changed != '0' + needs: + - check_and_test + - files_changed + permissions: + contents: read + packages: write strategy: matrix: platform: @@ -42,8 +173,15 @@ jobs: name: rayhunter-check-${{ matrix.platform.name }} path: target/release/rayhunter-check${{ matrix.platform.os == 'windows-latest' && '.exe' || '' }} if-no-files-found: error + build_rootshell: + if: needs.files_changed.outputs.rootshell_changed != '0' + needs: + - check_and_test + - files_changed runs-on: ubuntu-latest + permissions: + contents: read steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable @@ -56,7 +194,15 @@ jobs: name: rootshell path: target/armv7-unknown-linux-musleabihf/firmware/rootshell if-no-files-found: error + build_rayhunter: + if: needs.files_changed.outputs.daemon_changed != '0' + needs: + - check_and_test + - files_changed + permissions: + contents: read + packages: write strategy: matrix: device: @@ -88,9 +234,16 @@ jobs: name: rayhunter-daemon-${{ matrix.device.name }} path: target/armv7-unknown-linux-musleabihf/firmware/rayhunter-daemon if-no-files-found: error + build_rust_installer: + if: needs.files_changed.outputs.installer_changed != '0' + permissions: + contents: read + packages: write needs: - build_rayhunter + - files_changed + - windows_installer_check_and_test strategy: matrix: platform: @@ -124,6 +277,9 @@ jobs: if-no-files-found: error build_release_zip: + permissions: + contents: read + packages: write needs: - build_rayhunter_check - build_rootshell diff --git a/.github/workflows/mdbook.yaml b/.github/workflows/mdbook.yaml deleted file mode 100644 index 7434dc0..0000000 --- a/.github/workflows/mdbook.yaml +++ /dev/null @@ -1,47 +0,0 @@ -# On Repository Settings > Pages > Build and deployment -# Set "Source" to GitHub Actions. -name: Documentation -on: - push: - branches: ["main"] - pull_request: - branches: ["main"] - -jobs: - mdbook_test: - name: Test mdBook Documentation builds - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Install mdBook - run: | - cargo install mdbook --no-default-features --features search --vers "^0.4" --locked - - name: Test mdBook - run: mdbook test - - mdbook_publish: - if: ${{ github.event_name != 'pull_request' }} - needs: mdbook_test - permissions: - pages: write - contents: write - id-token: write - name: Publish mdBook to Github Pages - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Install mdBook - run: | - cargo install mdbook --no-default-features --features search --vers "^0.4" --locked - - - name: Build mdBook - run: mdbook build - - - name: Setup Pages - uses: actions/configure-pages@v4 - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - path: book - - name: Deploy to Github Pages - uses: actions/deploy-pages@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..c75775c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,48 @@ +# To use: navigate on Github to Actions, select "Release rayhunter" on the left, click "Run workflow" > "Run workflow" on the right. +# https://github.com/EFForg/rayhunter/actions/workflows/release.yml +name: Release rayhunter +on: + workflow_dispatch: + +env: + GH_TOKEN: ${{ github.token }} + +jobs: + check_version_same: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + - name: Ensure all Cargo.toml files have the same version defined. + run: | + defined_versions=$(find lib bin installer rootshell telcom-parser -name Cargo.toml -exec grep ^version {} \; | uniq | wc -l) + find lib bin installer rootshell telcom-parser -name Cargo.toml -exec grep ^version {} \; + echo number of defined versions = $defined_versions + if [ $defined_versions != "1" ] + then + echo "all Cargo.toml files must have the same version defined" + exit 1 + fi + + main: + needs: check_version_same + permissions: + contents: write + id-token: write + packages: write + pages: write + uses: ./.github/workflows/main.yml + + release: + runs-on: ubuntu-latest + needs: main + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 + - name: Create release + run: | + version=$(grep ^version lib/Cargo.toml | cut -d' ' -f3 | tr -d '"') + gh release create --generate-notes -t "Rayhunter v$version" "v$version" rayhunter-v${version}/rayhunter-*