From 0d8bbc658acf617b82cbdb83e1fcaa21516d4db1 Mon Sep 17 00:00:00 2001 From: mramotowski Date: Wed, 4 Feb 2026 11:01:40 +0100 Subject: [PATCH] ci: consolidate and improve GHA workflows - Reuse checkout/setup steps via YAML anchors - Standardize formatting and add permissions defaults - Simplify CodeQL build-mode handling - Tidy workflow commands and spacing - Fix Tauri build option handling in Windows installer Signed-off-by: mramotowski --- .github/workflows/backend-lint-and-test.yaml | 23 +-- .github/workflows/build.yaml | 8 +- .github/workflows/codeql.yaml | 14 +- .github/workflows/dependency-review.yaml | 9 +- .github/workflows/docs.yaml | 7 + .github/workflows/docs_stable.yaml | 7 + .github/workflows/lib-lint-and-test.yaml | 15 +- .github/workflows/pr-security-scan.yaml | 49 ------ .github/workflows/pr_comment_trigger.yaml | 161 ------------------ .github/workflows/publish.yaml | 34 ++-- .../workflows/renovate-config-validator.yml | 5 +- .github/workflows/scorecard.yaml | 2 +- .github/workflows/security-scan.yaml | 42 +++-- .github/workflows/stale_marker.yaml | 6 +- .github/workflows/ui-lint-and-test.yaml | 91 +++------- .github/workflows/windows-installer.yml | 35 ++-- 16 files changed, 129 insertions(+), 379 deletions(-) delete mode 100644 .github/workflows/pr-security-scan.yaml delete mode 100644 .github/workflows/pr_comment_trigger.yaml diff --git a/.github/workflows/backend-lint-and-test.yaml b/.github/workflows/backend-lint-and-test.yaml index d2c188a27c0..633fe7f1b17 100644 --- a/.github/workflows/backend-lint-and-test.yaml +++ b/.github/workflows/backend-lint-and-test.yaml @@ -27,7 +27,8 @@ jobs: outputs: run_workflow: ${{ steps.check_paths.outputs.run }} steps: - - name: Checkout repository + - &checkout + name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false @@ -52,10 +53,7 @@ jobs: permissions: contents: read # to checkout code steps: - - name: Checkout repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false + - *checkout - name: Install uv and set the Python version uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6 @@ -90,31 +88,26 @@ jobs: - name: Check imports with import-linter if: matrix.os == 'ubuntu-latest' working-directory: application/backend - run: | - uv run lint-imports + run: uv run lint-imports - name: Check source code with Pyrefly if: matrix.os == 'ubuntu-latest' working-directory: application/backend - run: | - uv run pyrefly check + run: uv run pyrefly check - name: Run unit tests working-directory: application/backend - run: | - uv run pytest tests/unit + run: uv run pytest tests/unit - name: Run ubuntu integration tests if: matrix.os == 'ubuntu-latest' working-directory: application/backend - run: | - uv run pytest tests/integration + run: uv run pytest tests/integration - name: Run windows integration tests # Skip tests with docker issues on Windows if: matrix.os == 'windows-latest' working-directory: application/backend - run: | - uv run pytest --ignore=tests/integration/stream/test_ip_camera_stream.py --ignore=tests/integration/services/dispatchers/test_mqtt.py tests/integration + run: uv run pytest --ignore=tests/integration/stream/test_ip_camera_stream.py --ignore=tests/integration/services/dispatchers/test_mqtt.py tests/integration required_check: name: Required Check backend-lint-and-test diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 9d79197c7e3..404a783d0ad 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -28,7 +28,8 @@ jobs: outputs: run_workflow: ${{ steps.check_paths.outputs.run }} steps: - - name: Checkout repository + - &checkout + name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false @@ -53,10 +54,7 @@ jobs: permissions: contents: read steps: - - name: Checkout repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false + - *checkout - name: Initial cleanup uses: open-edge-platform/geti-ci/actions/cleanup-runner@d30e32248aa6bd06adeda7129b50a38bdbceca12 diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 7c67e9e22e0..faeb0475a5c 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -25,7 +25,8 @@ jobs: run_actions: "${{ steps.prepare_outputs.outputs.run_actions }}" run_rust: "${{ steps.prepare_outputs.outputs.run_rust }}" steps: - - name: Checkout repository + - &checkout + name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false @@ -92,23 +93,16 @@ jobs: matrix: include: - language: actions - build-mode: none run: ${{ needs.check_paths.outputs.run_actions || 'true' }} - language: python - build-mode: none run: ${{ needs.check_paths.outputs.run_python || 'true' }} - language: javascript-typescript - build-mode: none run: ${{ needs.check_paths.outputs.run_javascript_typescript || 'true' }} - language: rust - build-mode: none run: ${{ needs.check_paths.outputs.run_rust || 'true' }} steps: - - name: Checkout repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false + - *checkout # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL @@ -116,7 +110,7 @@ jobs: if: ${{ matrix.run == 'true' }} with: languages: ${{ matrix.language }} - build-mode: ${{ matrix.build-mode }} + build-mode: none queries: security-extended - name: Perform CodeQL Analysis diff --git a/.github/workflows/dependency-review.yaml b/.github/workflows/dependency-review.yaml index e4f04eab904..a9a932516b5 100644 --- a/.github/workflows/dependency-review.yaml +++ b/.github/workflows/dependency-review.yaml @@ -1,16 +1,19 @@ name: Dependency Review -on: [pull_request] +on: + pull_request: -permissions: - contents: read +permissions: {} # No permissions by default jobs: dependency-review: runs-on: ubuntu-24.04 + permissions: + contents: read steps: - name: "Checkout Repository" uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false + - name: "Dependency Review" uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2 diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 4e884da7be3..3d2ba015c9f 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -18,18 +18,22 @@ jobs: uses: open-edge-platform/geti-ci/actions/cleanup-runner@d30e32248aa6bd06adeda7129b50a38bdbceca12 with: type: "initial" + - name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false + - name: Set up Python uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 with: python-version: "3.12" + - name: Install dependencies working-directory: library run: | python -m pip install uv + - name: Build-Docs working-directory: library run: | @@ -39,6 +43,7 @@ jobs: cd docs make clean make html + - name: Create gh-pages branch run: | if [[ ${{github.event_name}} == 'workflow_dispatch' ]]; then @@ -67,6 +72,7 @@ jobs: else echo "Branch gh-pages already exists" fi + - name: Commit docs to gh-pages branch working-directory: library env: @@ -88,6 +94,7 @@ jobs: fi git add ./latest "$RELEASE_VERSION" git commit -m "Update documentation" -a || true + - name: Push changes uses: ad-m/github-push-action@77c5b412c50b723d2a4fbc6d71fb5723bcd439aa # v1.0.0 with: diff --git a/.github/workflows/docs_stable.yaml b/.github/workflows/docs_stable.yaml index a54fe777763..b23370aaa11 100644 --- a/.github/workflows/docs_stable.yaml +++ b/.github/workflows/docs_stable.yaml @@ -16,19 +16,23 @@ jobs: uses: open-edge-platform/geti-ci/actions/cleanup-runner@d30e32248aa6bd06adeda7129b50a38bdbceca12 with: type: "initial" + - name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: fetch-depth: 0 # otherwise, you will failed to push refs to dest repo persist-credentials: false + - name: Set up Python uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 with: python-version: "3.12" + - name: Install dependencies working-directory: library run: | python -m pip install uv + - name: Build-Docs working-directory: library run: | @@ -38,6 +42,7 @@ jobs: cd docs make clean make html + - name: Create gh-pages branch run: | echo RELEASE_VERSION=${GITHUB_REF#refs/*/} >> $GITHUB_ENV @@ -61,6 +66,7 @@ jobs: else echo "Branch gh-pages already exists" fi + - name: Commit docs to gh-pages branch working-directory: library env: @@ -80,6 +86,7 @@ jobs: git config --local user.name "GitHub Action" git add ./stable "$RELEASE_VERSION" git commit -m "Update documentation" -a || true + - name: Push changes uses: ad-m/github-push-action@77c5b412c50b723d2a4fbc6d71fb5723bcd439aa # v1.0.0 with: diff --git a/.github/workflows/lib-lint-and-test.yaml b/.github/workflows/lib-lint-and-test.yaml index 8be4d850284..ea51902e712 100644 --- a/.github/workflows/lib-lint-and-test.yaml +++ b/.github/workflows/lib-lint-and-test.yaml @@ -28,7 +28,8 @@ jobs: outputs: run_workflow: ${{ steps.check_paths.outputs.run }} steps: - - name: Checkout repository + - &checkout + name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false @@ -49,10 +50,7 @@ jobs: permissions: contents: read steps: - - name: Checkout repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false + - *checkout - name: Install uv and set the Python version uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6 @@ -77,8 +75,7 @@ jobs: - name: Check source code with Pyrefly working-directory: library - run: | - uv run pyrefly check --baseline=pyrefly-baseline.json + run: uv run pyrefly check --baseline=pyrefly-baseline.json unit-tests: runs-on: [self-hosted, linux, x64, dev, dmount] @@ -87,7 +84,6 @@ jobs: # The id-token permission is required by Codecov to use OIDC id-token: write needs: - - code-quality-checks - check-paths if: needs.check-paths.outputs.run_workflow == 'true' timeout-minutes: 120 @@ -97,6 +93,7 @@ jobs: python-version: ["3.10", "3.14"] name: unit-tests-with-Python${{ matrix.python-version }} steps: + # YAML anchors not used cause currently zizmor don't support them in matrix strategies - name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: @@ -149,7 +146,6 @@ jobs: permissions: contents: read needs: - - unit-tests - check-paths strategy: fail-fast: false @@ -165,6 +161,7 @@ jobs: - "semantic_segmentation" name: integration-tests-${{ matrix.task }}-py${{ matrix.python-version }} steps: + # YAML anchors aren't used because Zizmor fails here and support for them is best-effort for now - name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: diff --git a/.github/workflows/pr-security-scan.yaml b/.github/workflows/pr-security-scan.yaml deleted file mode 100644 index 3a9299536ed..00000000000 --- a/.github/workflows/pr-security-scan.yaml +++ /dev/null @@ -1,49 +0,0 @@ -name: Security Scans on PR - -on: - pull_request: - branches: - - develop - - release/** - -permissions: {} - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - -jobs: - zizmor-scan-pr: - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false - - name: Run Zizmor scan - uses: open-edge-platform/geti-ci/actions/zizmor@d30e32248aa6bd06adeda7129b50a38bdbceca12 - with: - scan-scope: "changed" - severity-level: "MEDIUM" - confidence-level: "LOW" - fail-on-findings: true - - bandit-scan-pr: - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false - - name: Run Bandit scan - uses: open-edge-platform/geti-ci/actions/bandit@d30e32248aa6bd06adeda7129b50a38bdbceca12 - with: - scan-scope: "changed" - severity-level: "LOW" - confidence-level: "LOW" - config_file: ".ci/ipas_default.config" - fail-on-findings: true diff --git a/.github/workflows/pr_comment_trigger.yaml b/.github/workflows/pr_comment_trigger.yaml deleted file mode 100644 index 98333d83ac5..00000000000 --- a/.github/workflows/pr_comment_trigger.yaml +++ /dev/null @@ -1,161 +0,0 @@ -name: Pull Request Comment Triggered Integration Test - -on: - issue_comment: - types: [created] - -env: - COMMENT_BODY: ${{ github.event.comment.body }} - -permissions: - pull-requests: write - contents: read - issues: read - -jobs: - pr-triggered-integration-test: - if: | - github.event.issue.pull_request && - startsWith(github.event.comment.body, '/run ') - runs-on: [self-hosted, linux, x64, dev, dmount] - name: PR-Comment-Integration-Tests - steps: - - name: Is comment allowed? - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const actorPermission = (await github.rest.repos.getCollaboratorPermissionLevel({ - ...context.repo, - username: context.actor - })).data.permission - const isPermitted = ['write', 'admin'].includes(actorPermission) - if (!isPermitted) { - const errorMessage = 'Only users with write permission to the repository can run GitHub commands' - await github.rest.issues.createComment({ - ...context.repo, - issue_number: context.issue.number, - body: errorMessage, - }) - core.setFailed(errorMessage) - return - } - - - name: Get PR Info - id: pr - env: - PR_NUMBER: ${{ github.event.issue.number }} - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GH_REPO: ${{ github.repository }} - COMMENT_AT: ${{ github.event.comment.created_at }} - run: | - pr="$(gh api /repos/${GH_REPO}/pulls/${PR_NUMBER})" - head_sha="$(echo "$pr" | jq -r .head.sha)" - pushed_at="$(echo "$pr" | jq -r .head.repo.pushed_at)" - - if [[ $(date -d "$pushed_at" +%s) -gt $(date -d "$COMMENT_AT" +%s) ]]; then - echo "Updating is not allowed because the PR was pushed to (at $pushed_at) after the triggering comment was issued (at $COMMENT_AT)" - exit 1 - fi - - echo "head_sha=$head_sha" >> $GITHUB_OUTPUT - - - name: Checkout the branch from the PR that triggered the job - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh pr checkout ${{ github.event.issue.number }} - - - name: Validate the fetched branch HEAD revision - env: - EXPECTED_SHA: ${{ steps.pr.outputs.head_sha }} - run: | - actual_sha="$(git rev-parse HEAD)" - - if [[ "$actual_sha" != "$EXPECTED_SHA" ]]; then - echo "The HEAD of the checked out branch ($actual_sha) differs from the HEAD commit available at the time when trigger comment was submitted ($EXPECTED_SHA)" - exit 1 - fi - - - name: Print current branch - run: echo "$(git branch)" - - - name: Install Python - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6 - with: - python-version: "3.12" - - - name: Install tox - working-directory: library - run: | - pip install '.[dev]' - - - name: Extract, Validate, and Run Integration Test - working-directory: library - id: tests - run: | - ALLOWED_TASKS=("all" "detection" "instance_segmentation" "semantic_segmentation" "multi_class_cls" "multi_label_cls" "h_label_cls" "anomaly_classification" "keypoint_detection") - - # Ensure comment starts with "/run " and extract task name - if [[ "$COMMENT_BODY" =~ ^/run\ ([a-zA-Z0-9_-]+)$ ]]; then - TASK_NAME="${BASH_REMATCH[1]}" - else - echo "❌ Invalid format. Use '/run '" - exit 1 - fi - - # Validate the extracted task name - if [[ ! " ${ALLOWED_TASKS[@]} " =~ " ${TASK_NAME} " ]]; then - echo "❌ Invalid task: $TASK_NAME. Allowed tasks: ${ALLOWED_TASKS[*]}" - exit 1 - fi - - echo "✅ Running integration test for: $TASK_NAME" - tox -vv -e "integration-test-${TASK_NAME}" - - - name: Update PR description with workflow run link and result - if: always() # Ensure this runs even if the job fails - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} # Or your PAT if needed - script: | - const status = '${{ steps.tests.outcome }}'; // success, failure, skipped - const emoji = { - success: "✅", - failure: "❌", - skipped: "⚠️", - }[status] || "❓"; - - const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${process.env.GITHUB_RUN_ID}`; - const { data: pr } = await github.rest.pulls.get({ - owner: context.repo.owner, - repo: context.repo.repo, - pull_number: context.issue.number - }); - - const { data: commits } = await github.rest.pulls.listCommits({ - owner: context.repo.owner, - repo: context.repo.repo, - pull_number: context.issue.number - }); - const lastCommit = commits[commits.length - 1]; - const lastCommitMsg = lastCommit.commit.message.split('\n')[0]; - - const tag = ""; - const runSection = `${tag} - - ## 🚀 Integration Run Summary - - - **Last Commit:** ${lastCommitMsg} - - **Result:** ${emoji} ${status.toUpperCase()} - - **Workflow Run:** [View Run](${runUrl}) - `; - - const newBody = pr.body.includes(tag) - ? pr.body.replace(new RegExp(`${tag}[\\s\\S]*?(\n|$)`), runSection) - : `${pr.body}\n\n${runSection}`; - - await github.rest.pulls.update({ - owner: context.repo.owner, - repo: context.repo.repo, - pull_number: context.issue.number, - body: newBody - }); diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index f1e6c58c49f..bd89d21ead1 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -9,55 +9,51 @@ permissions: {} # No permissions by default jobs: build: - name: Build + name: Build & publish package runs-on: ubuntu-latest + environment: pypi + permissions: + contents: write # required by svenstaro/upload-release-action + id-token: write # required by trusted publisher steps: - name: Checkout uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false + - name: Set up Python 3.12 uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 with: python-version: "3.12" + - name: Install build tools run: python -m pip install build + - name: Build sdist run: python -m build --sdist library/ + - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: artifact-sdist path: library/dist/*.tar.gz + - name: Build wheel run: python -m build --wheel library/ + - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: artifact-wheel path: library/dist/*.whl - publish_package: - name: Publish package - needs: [build] - environment: pypi - runs-on: ubuntu-latest - permissions: - contents: write # required by svenstaro/upload-release-action - id-token: write # required by trusted publisher - steps: - - name: Download artifacts - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 - with: - path: library/dist - pattern: artifact-* - merge-multiple: true - # to determine where to publish the package distribution to PyPI or TestPyPI + # Determine where to publish the package distribution to PyPI or TestPyPI - name: Check tag id: check-tag uses: actions-ecosystem/action-regex-match@9e6c4fb3d5e898f505be7a1fb6e7b0a278f6665b # v2.0.2 with: text: ${{ github.ref }} regex: '^refs/tags/[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+rc[0-9]+|rc[0-9]+)?$' - - name: Upload package distributions to github + + - name: Upload package distributions to GitHub if: ${{ steps.check-tag.outputs.match != '' }} uses: svenstaro/upload-release-action@6b7fa9f267e90b50a19fef07b3596790bb941741 # v2 with: @@ -66,9 +62,11 @@ jobs: tag: ${{ github.ref }} overwrite: true file_glob: true + - name: Publish package distributions to PyPI if: ${{ steps.check-tag.outputs.match != '' }} uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 + - name: Publish package distributions to TestPyPI if: ${{ steps.check-tag.outputs.match == '' }} uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 diff --git a/.github/workflows/renovate-config-validator.yml b/.github/workflows/renovate-config-validator.yml index e8dd5f933d8..221ff706c9d 100644 --- a/.github/workflows/renovate-config-validator.yml +++ b/.github/workflows/renovate-config-validator.yml @@ -17,8 +17,7 @@ on: paths: - ".github/renovate.json5" -permissions: - contents: read +permissions: {} # No permissions by default concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -27,6 +26,8 @@ concurrency: jobs: validate: runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Checkout configuration uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 diff --git a/.github/workflows/scorecard.yaml b/.github/workflows/scorecard.yaml index 509059ea650..b3b74d3e5ca 100644 --- a/.github/workflows/scorecard.yaml +++ b/.github/workflows/scorecard.yaml @@ -8,7 +8,7 @@ on: - cron: "0 2 * * *" workflow_dispatch: -permissions: {} +permissions: {} # No permissions by default on workflow level jobs: analysis: diff --git a/.github/workflows/security-scan.yaml b/.github/workflows/security-scan.yaml index 8f453a46e19..320f2664f82 100644 --- a/.github/workflows/security-scan.yaml +++ b/.github/workflows/security-scan.yaml @@ -14,17 +14,24 @@ name: "Security scan" on: - schedule: - # Run security checks every day at 2 AM UTC - - cron: "0 2 * * *" - workflow_dispatch: + pull_request: + branches: + - develop + - release/** push: branches: - develop - "release/**" + schedule: + - cron: "0 2 * * *" # Run security checks every day at 2 AM UTC + workflow_dispatch: permissions: {} # No permissions by default +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: zizmor-scan: runs-on: ubuntu-latest @@ -32,17 +39,19 @@ jobs: contents: read security-events: write # Needed to upload the results to code-scanning dashboard steps: - - name: Checkout code + - &checkout + name: Checkout code uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false + - name: Run Zizmor scan uses: open-edge-platform/geti-ci/actions/zizmor@d30e32248aa6bd06adeda7129b50a38bdbceca12 with: - scan-scope: "all" - severity-level: "LOW" + scan-scope: ${{ github.event_name == 'pull_request' && 'changed' || 'all' }} + severity-level: ${{ github.event_name == 'pull_request' && 'MEDIUM' || 'LOW' }} confidence-level: "LOW" - fail-on-findings: false # reports only + fail-on-findings: ${{ github.event_name == 'pull_request' && 'true' || 'false' }} bandit-scan: runs-on: ubuntu-latest @@ -50,29 +59,26 @@ jobs: contents: read security-events: write # Needed to upload the results to code-scanning dashboard steps: - - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false + - *checkout + - name: Run Bandit scan uses: open-edge-platform/geti-ci/actions/bandit@d30e32248aa6bd06adeda7129b50a38bdbceca12 with: - scan-scope: "all" + scan-scope: ${{ github.event_name == 'pull_request' && 'changed' || 'all' }} severity-level: "LOW" confidence-level: "LOW" config_file: ".ci/ipas_default.config" - fail-on-findings: false # reports only + fail-on-findings: ${{ github.event_name == 'pull_request' && 'true' || 'false' }} trivy-scan: runs-on: ubuntu-latest + if: github.event_name != 'pull_request' permissions: contents: read security-events: write # Needed to upload the results to code-scanning dashboard steps: - - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false + - *checkout + - name: Run Trivy scan id: trivy uses: open-edge-platform/geti-ci/actions/trivy@d30e32248aa6bd06adeda7129b50a38bdbceca12 diff --git a/.github/workflows/stale_marker.yaml b/.github/workflows/stale_marker.yaml index 5625669bd2b..11e9976f12c 100644 --- a/.github/workflows/stale_marker.yaml +++ b/.github/workflows/stale_marker.yaml @@ -3,12 +3,14 @@ on: schedule: - cron: "30 1 * * *" -# Declare default permissions as read only. -permissions: read-all +permissions: {} # No permissions by default jobs: stale: runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write steps: - uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1 with: diff --git a/.github/workflows/ui-lint-and-test.yaml b/.github/workflows/ui-lint-and-test.yaml index 0bfb8155cfd..04ba43c22b4 100644 --- a/.github/workflows/ui-lint-and-test.yaml +++ b/.github/workflows/ui-lint-and-test.yaml @@ -28,7 +28,8 @@ jobs: outputs: run_workflow: ${{ steps.check_paths.outputs.run }} steps: - - name: Checkout repository + - &checkout + name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false @@ -51,10 +52,7 @@ jobs: permissions: contents: read # to checkout code steps: - - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false + - *checkout - name: Install uv and set the Python version uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6 @@ -95,18 +93,17 @@ jobs: permissions: contents: read # to checkout code steps: - - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false + - *checkout - - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 + - &setup-node + uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 id: setup-node with: node-version-file: application/ui/.nvmrc package-manager-cache: false - - name: Install dependencies + - &install-dependencies + name: Install dependencies working-directory: "application/ui" run: npm ci @@ -133,28 +130,21 @@ jobs: permissions: contents: read # to checkout code steps: - - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false + - *checkout - - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 - id: setup-node - with: - node-version-file: application/ui/.nvmrc - package-manager-cache: false + - *setup-node - - name: Install dependencies - working-directory: "application/ui" - run: npm ci + - *install-dependencies - - name: Download OpenAPI spec artifact + - &download-openapi-spec + name: Download OpenAPI spec artifact uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: openapi-spec path: application/ui/src/api - - name: Build OpenAPI type definitions + - &build-openapi-types + name: Build OpenAPI type definitions working-directory: "application/ui" run: npm run build:api @@ -185,30 +175,15 @@ jobs: contents: read pull-requests: write steps: - - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false + - *checkout - - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 - id: setup-node - with: - node-version-file: application/ui/.nvmrc - package-manager-cache: false + - *setup-node - - name: Install dependencies - working-directory: "application/ui" - run: npm ci + - *install-dependencies - - name: Download OpenAPI spec artifact - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 - with: - name: openapi-spec - path: application/ui/src/api + - *download-openapi-spec - - name: Build OpenAPI type definitions - working-directory: "application/ui" - run: npm run build:api + - *build-openapi-types - name: UI Unit tests working-directory: "application/ui" @@ -295,21 +270,11 @@ jobs: container: image: mcr.microsoft.com/playwright:v1.57.0-jammy@sha256:6aca677c27a967caf7673d108ac67ffaf8fed134f27e17b27a05464ca0ace831 steps: - - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false - ref: ${{ inputs.ref || '' }} + - *checkout - - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 - id: setup-node - with: - node-version-file: application/ui/.nvmrc - package-manager-cache: false + - *setup-node - - name: Install dependencies - working-directory: "application/ui" - run: npm ci + - *install-dependencies - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: @@ -320,15 +285,9 @@ jobs: working-directory: "application/ui" run: tar -xzf dist.tar.gz - - name: Download OpenAPI spec artifact - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 - with: - name: openapi-spec - path: application/ui/src/api + - *download-openapi-spec - - name: Build OpenAPI type definitions - working-directory: "application/ui" - run: npm run build:api + - *build-openapi-types - name: Run Playwright tests working-directory: "application/ui" diff --git a/.github/workflows/windows-installer.yml b/.github/workflows/windows-installer.yml index 6cbe7ec4939..445b722c284 100644 --- a/.github/workflows/windows-installer.yml +++ b/.github/workflows/windows-installer.yml @@ -50,6 +50,8 @@ env: MAKEAPP_PATH: "C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.26100.0\\x64\\makeappx.exe" SIGNTOOL_PATH: "C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.26100.0\\x64\\signtool.exe" +permissions: {} # No permissions by default on workflow level + jobs: windows-installer: name: Build windows installer @@ -67,7 +69,7 @@ jobs: run: | Write-Host "DEBUG_BUILD=$env:DEBUG_BUILD" - $TARGET = $(IF ($env:DEBUG_BUILD -eq "true") {"debug"} else {"release"}) + $TARGET = $(IF ($env:DEBUG_BUILD -eq "true") {"debug"} else {"release"}) $UI_BUILD_PATH = $env:UI_TARGET_PATH + "\" + $TARGET Write-Host "UI_BUILD_PATH=$UI_BUILD_PATH" Add-Content -Path $env:GITHUB_ENV -Value "UI_BUILD_PATH=$UI_BUILD_PATH" @@ -110,8 +112,7 @@ jobs: uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2 with: save-if: ${{ startsWith(github.ref_name, 'release/') || github.ref_name == 'develop' }} - workspaces: | - application\ui\src-tauri -> target + workspaces: application\ui\src-tauri -> target # Build backend @@ -127,13 +128,11 @@ jobs: working-directory: application/backend env: PYTHONPATH: "." - run: | - uv run --no-sync app/cli.py gen-api --target-path .build/openapi-spec.json + run: uv run --no-sync app/cli.py gen-api --target-path .build/openapi-spec.json - name: Build executable working-directory: application/backend - run: | - uv run pyinstaller --noconfirm geti-tune.spec + run: uv run pyinstaller --noconfirm geti-tune.spec # Copy backend artifacts to UI @@ -143,10 +142,9 @@ jobs: cp -r ${{ env.BACKEND_DIST_PATH }}\geti-tune-backend.exe ${{ env.UI_SRC_TAURI_PATH }}\geti-tune-backend-x86_64-pc-windows-msvc.exe - name: Copy OpenAPI spec - run: | - cp -r ${{ env.BACKEND_BUILD_PATH }}\openapi-spec.json ${{ env.UI_SRC_API_PATH }} + run: cp -r ${{ env.BACKEND_BUILD_PATH }}\openapi-spec.json ${{ env.UI_SRC_API_PATH }} - # Build UI with Tauri + # Build UI with Tauri - name: Setup Node & npm uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 @@ -173,20 +171,17 @@ jobs: run: npm run build:api - name: Build Tauri app - if: inputs.debug_build == true - env: - PUBLIC_API_URL: http://localhost:9100 - working-directory: application/ui - run: | - cargo tauri build --debug - - - name: Build Tauri app - if: inputs.debug_build == false env: PUBLIC_API_URL: http://localhost:9100 + DEBUG_BUILD: ${{ inputs.debug_build }} working-directory: application/ui run: | - cargo tauri build + $OPTIONS = @() + if ($env:DEBUG_BUILD -eq "true") { + $OPTIONS += "--debug" + } + Write-Host "Building Tauri app with options: $($OPTIONS -join ' ')" + cargo tauri build @OPTIONS # Build MSIX bundle