diff --git a/.github/workflows/downstream_benchmarks.yml b/.github/workflows/downstream_benchmarks.yml index 7d6b89fedd..f77d1ba65c 100644 --- a/.github/workflows/downstream_benchmarks.yml +++ b/.github/workflows/downstream_benchmarks.yml @@ -2,14 +2,13 @@ name: Downstream - Integration Tests on: # Enables the workflow to run on PRs from forks. - # CI will only run once the PR is labeled as "Safe for CI", in order to prevent stealing of secrets. + # CI will only run for trusted users, to prevent stealing of secrets. pull_request_target: branches: [main] # Benchmarks aren't branched, so they will only ever work against current main. types: - opened - reopened - synchronize - - labeled paths-ignore: - 'LICENSE*' - '.gitignore' @@ -18,17 +17,34 @@ on: - '*.txt' jobs: - safe_for_ci: - name: "Ensure that PR is safe for CI" + # Check if the user is a member of the organization; if so, allow the PR to sail through. + known_user: runs-on: ubuntu-latest + outputs: + is_member_of_org: ${{ steps.auth_check.outputs.authorized }} steps: - - name: Fail if not safe - if: ${{ !contains( github.event.pull_request.labels.*.name, 'Safe for CI') }} - shell: bash - run: - exit 1 + - id: auth_check + uses: morfien101/actions-authorized-user@v3 + with: + username: ${{ github.actor }} + org: "TimefoldAI" + whitelist: "timefold-release,dependabot[bot]" # We trust dependabot to not steal secrets. + github_token: ${{ secrets.JRELEASER_GITHUB_TOKEN }} # Release account is a Solver Gatekeeper. + # If the user is not a member, require a member to approve the PR. + approval_required: + needs: known_user + environment: + ${{ + github.event_name == 'pull_request_target' && + github.event.pull_request.head.repo.full_name != github.repository && + !needs.known_user.outputs.is_member_of_org && + 'external' || 'internal' + }} + runs-on: ubuntu-latest + steps: + - run: true build: - needs: safe_for_ci + needs: approval_required runs-on: ubuntu-latest concurrency: group: pr-${{ github.event_name }}-${{ github.head_ref }} diff --git a/.github/workflows/downstream_enterprise.yml b/.github/workflows/downstream_enterprise.yml index d9a4bd24d4..6ec53ee6e6 100644 --- a/.github/workflows/downstream_enterprise.yml +++ b/.github/workflows/downstream_enterprise.yml @@ -2,14 +2,13 @@ name: Downstream - Timefold Solver Enterprise Edition on: # Enables the workflow to run on PRs from forks. - # CI will only run once the PR is labeled as "Safe for CI", in order to prevent stealing of secrets. + # CI will only run for trusted users, to prevent stealing of secrets. pull_request_target: branches: [main, '*.x'] types: - opened - reopened - synchronize - - labeled paths-ignore: - 'LICENSE*' - '.gitignore' @@ -18,17 +17,34 @@ on: - '*.txt' jobs: - safe_for_ci: - name: "Ensure that PR is safe for CI" + # Check if the user is a member of the organization; if so, allow the PR to sail through. + known_user: runs-on: ubuntu-latest + outputs: + is_member_of_org: ${{ steps.auth_check.outputs.authorized }} steps: - - name: Fail if not safe - if: ${{ !contains( github.event.pull_request.labels.*.name, 'Safe for CI') }} - shell: bash - run: - exit 1 + - id: auth_check + uses: morfien101/actions-authorized-user@v3 + with: + username: ${{ github.actor }} + org: "TimefoldAI" + whitelist: "timefold-release,dependabot[bot]" # We trust dependabot to not steal secrets. + github_token: ${{ secrets.JRELEASER_GITHUB_TOKEN }} # Release account is a Solver Gatekeeper. + # If the user is not a member, require a member to approve the PR. + approval_required: + needs: known_user + environment: + ${{ + github.event_name == 'pull_request_target' && + github.event.pull_request.head.repo.full_name != github.repository && + !needs.known_user.outputs.is_member_of_org && + 'external' || 'internal' + }} + runs-on: ubuntu-latest + steps: + - run: true build: - needs: safe_for_ci + needs: approval_required runs-on: ubuntu-latest concurrency: group: downstream-enterprise-${{ github.event_name }}-${{ github.head_ref }} diff --git a/.github/workflows/downstream_python_enterprise.yml b/.github/workflows/downstream_python_enterprise.yml index 8663741f72..a155bf7e70 100644 --- a/.github/workflows/downstream_python_enterprise.yml +++ b/.github/workflows/downstream_python_enterprise.yml @@ -3,14 +3,13 @@ name: Downstream - Timefold Solver Enterprise for Python on: # Enables the workflow to run on PRs from forks. - # CI will only run once the PR is labeled as "Safe for CI", in order to prevent stealing of secrets. + # CI will only run for trusted users, to prevent stealing of secrets. pull_request_target: branches: [ main, '*.x' ] types: - opened - reopened - synchronize - - labeled paths-ignore: - 'LICENSE*' - '.gitignore' @@ -23,17 +22,34 @@ defaults: shell: bash jobs: - safe_for_ci: - name: "Ensure that PR is safe for CI" + # Check if the user is a member of the organization; if so, allow the PR to sail through. + known_user: runs-on: ubuntu-latest + outputs: + is_member_of_org: ${{ steps.auth_check.outputs.authorized }} steps: - - name: Fail if not safe - if: ${{ !contains( github.event.pull_request.labels.*.name, 'Safe for CI') }} - shell: bash - run: - exit 1 + - id: auth_check + uses: morfien101/actions-authorized-user@v3 + with: + username: ${{ github.actor }} + org: "TimefoldAI" + whitelist: "timefold-release,dependabot[bot]" # We trust dependabot to not steal secrets. + github_token: ${{ secrets.JRELEASER_GITHUB_TOKEN }} # Release account is a Solver Gatekeeper. + # If the user is not a member, require a member to approve the PR. + approval_required: + needs: known_user + environment: + ${{ + github.event_name == 'pull_request_target' && + github.event.pull_request.head.repo.full_name != github.repository && + !needs.known_user.outputs.is_member_of_org && + 'external' || 'internal' + }} + runs-on: ubuntu-latest + steps: + - run: true build: - needs: safe_for_ci + needs: approval_required concurrency: group: downstream-enterprise-python-${{ github.event_name }}-${{ github.head_ref }} cancel-in-progress: true diff --git a/.github/workflows/safe_for_ci.yml b/.github/workflows/safe_for_ci.yml deleted file mode 100644 index 6ae1358c23..0000000000 --- a/.github/workflows/safe_for_ci.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Check if PR safe for CI - -on: - # Workflow always runs from the blessed repo; cannot be forged. - pull_request_target: - types: [ opened ] - -jobs: - add_labels: - runs-on: ubuntu-latest - steps: - - name: checkout - uses: actions/checkout@v2 - - - - id: auth_check - uses: morfien101/actions-authorized-user@v3 - with: - username: ${{ github.actor }} - org: "TimefoldAI" - whitelist: "timefold-release,dependabot[bot]" # We trust dependabot to not steal secrets. - github_token: ${{ secrets.JRELEASER_GITHUB_TOKEN }} # Release account is a Solver Gatekeeper. - - name: Add labels - uses: actions-ecosystem/action-add-labels@v1 - if: ${{ steps.auth_check.outputs.authorized }} - with: - labels: | - Safe for CI - - name: Add labels - uses: actions-ecosystem/action-add-labels@v1 - if: ${{ !steps.auth_check.outputs.authorized }} - with: - labels: | - External Contribution \ No newline at end of file diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 0d936e2956..f1269cecc8 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -3,24 +3,43 @@ on: push: branches: - main - pull_request_target: # This workflow will be triggered by the opening, reopening, or updating of a PR, and the first run will not require approval. + # Enables the workflow to run on PRs from forks. + # CI will only run for trusted users, to prevent stealing of secrets. + pull_request_target: types: - opened - reopened - synchronize - labeled jobs: - safe_for_ci: - name: "Ensure that PR is safe for CI" + # Check if the user is a member of the organization; if so, allow the PR to sail through. + known_user: runs-on: ubuntu-latest + outputs: + is_member_of_org: ${{ steps.auth_check.outputs.authorized }} steps: - - name: Fail if not safe - if: ${{ !contains( github.event.pull_request.labels.*.name, 'Safe for CI') }} - shell: bash - run: - exit 1 + - id: auth_check + uses: morfien101/actions-authorized-user@v3 + with: + username: ${{ github.actor }} + org: "TimefoldAI" + whitelist: "timefold-release,dependabot[bot]" # We trust dependabot to not steal secrets. + github_token: ${{ secrets.JRELEASER_GITHUB_TOKEN }} # Release account is a Solver Gatekeeper. + # If the user is not a member, require a member to approve the PR. + approval_required: + needs: known_user + environment: + ${{ + github.event_name == 'pull_request_target' && + github.event.pull_request.head.repo.full_name != github.repository && + !needs.known_user.outputs.is_member_of_org && + 'external' || 'internal' + }} + runs-on: ubuntu-latest + steps: + - run: true build: - needs: safe_for_ci + needs: approval_required name: Build and analyze runs-on: ubuntu-latest steps: