diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 78d80e0..dd75e54 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,10 +11,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Clone the code - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version-file: go.mod diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml new file mode 100644 index 0000000..da71477 --- /dev/null +++ b/.github/workflows/e2e-tests.yml @@ -0,0 +1,52 @@ +name: E2E Tests + +on: + workflow_call: + secrets: + OP_CONNECT_CREDENTIALS: + description: '1Password Connect credentials' + required: true + OP_CONNECT_TOKEN: + description: '1Password Connect token' + required: true + OP_SERVICE_ACCOUNT_TOKEN: + description: '1Password service account token' + required: true + +jobs: + e2e-test: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version-file: go.mod + + - name: Install dependencies + run: go mod tidy + + - name: Create kind cluster + uses: helm/kind-action@v1 + with: + cluster_name: onepassword-operator-test-e2e + + # install cli to interact with item in 1Password to update/read using `testhelper/op` package + - name: Install 1Password CLI + uses: 1password/install-cli-action@v2 + with: + version: 2.32.0 + + - name: Create '1password-credentials.json' file + env: + OP_CONNECT_CREDENTIALS: ${{ secrets.OP_CONNECT_CREDENTIALS }} + run: | + echo "$OP_CONNECT_CREDENTIALS" > 1password-credentials.json + + - name: Run E2E tests + run: make test-e2e + env: + OP_CONNECT_TOKEN: ${{ secrets.OP_CONNECT_TOKEN }} + OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 764f661..7658346 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,10 +11,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Clone the code - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version-file: go.mod diff --git a/.github/workflows/ok-to-test.yml b/.github/workflows/ok-to-test.yml new file mode 100644 index 0000000..304afca --- /dev/null +++ b/.github/workflows/ok-to-test.yml @@ -0,0 +1,25 @@ +# Write comments "/ok-to-test " on a pull request. This will emit a repository_dispatch event. +name: Ok To Test + +on: + issue_comment: + types: [created] + +jobs: + ok-to-test: + runs-on: ubuntu-latest + permissions: + pull-requests: write # For adding reactions to the pull request comments + contents: write # For executing the repository_dispatch event + # Only run for PRs, not issue comments + if: ${{ github.event.issue.pull_request }} + steps: + - name: Slash Command Dispatch + uses: volodymyrZotov/slash-command-dispatch@7c1b623a2b0eba93f684c34f689a441f0be84cf1 # TODO: use peter-evans/slash-command-dispatch when fix for team permissions is released https://github.com/peter-evans/slash-command-dispatch/pull/424 + with: + token: ${{ secrets.GITHUB_TOKEN }} + reaction-token: ${{ secrets.GITHUB_TOKEN }} + issue-type: pull-request + commands: ok-to-test + # The repository permission level required by the user to dispatch commands. Only allows 1Password collaborators to run this. + permission: write diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index 10c93c8..a464497 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -43,7 +43,7 @@ jobs: name: Create Release Pull Request runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Parse release version id: get_version diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 22e87bc..589412f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: DOCKER_CLI_EXPERIMENTAL: "enabled" steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 diff --git a/.github/workflows/test-e2e-fork.yml b/.github/workflows/test-e2e-fork.yml new file mode 100644 index 0000000..e0ceb08 --- /dev/null +++ b/.github/workflows/test-e2e-fork.yml @@ -0,0 +1,56 @@ +name: E2E tests [fork] + +on: + repository_dispatch: + types: [ ok-to-test-command ] + +permissions: + contents: read + checks: write + +concurrency: + group: e2e-fork-${{ github.event.client_payload.pull_request.number || github.run_id }} + cancel-in-progress: true # cancel previous job runs for the same branch + +jobs: + e2e-tests: + uses: ./.github/workflows/e2e-tests.yml + if: | + github.event_name == 'repository_dispatch' && + github.event.client_payload.slash_command.args.named.sha != '' && + contains( + github.event.client_payload.pull_request.head.sha, + github.event.client_payload.slash_command.args.named.sha + ) + secrets: + OP_CONNECT_CREDENTIALS: ${{ secrets.OP_CONNECT_CREDENTIALS }} + OP_CONNECT_TOKEN: ${{ secrets.OP_CONNECT_TOKEN }} + OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} + + update-check-status: + needs: e2e-tests + runs-on: ubuntu-latest + if: always() && github.event_name == 'repository_dispatch' + steps: + - uses: actions/github-script@v6 + env: + ref: ${{ github.event.client_payload.pull_request.head.sha }} + conclusion: ${{ needs.e2e-tests.result }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { data: checks } = await github.rest.checks.listForRef({ + ...context.repo, + ref: process.env.ref + }); + + const check = checks.check_runs.filter(c => c.name === 'e2e-test'); + + const { data: result } = await github.rest.checks.update({ + ...context.repo, + check_run_id: check[0].id, + status: 'completed', + conclusion: process.env.conclusion + }); + + return result; diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index 65f3a3e..cc5897f 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -1,48 +1,43 @@ -name: Test E2E +name: E2E Tests on: pull_request: types: [opened, synchronize, reopened] branches: ['**'] # run for PRs targeting any branch (main and others) + paths-ignore: &ignore_paths + - 'docs/**' + - '*.md' + - '.golangci.yml' + - '.gitignore' + - '.dockerignore' + - 'LICENSE' + push: + branches: [main] + paths-ignore: *ignore_paths concurrency: group: e2e-${{ github.event.pull_request.head.ref }} - cancel-in-progress: true # cancel previous job runs for the same branch + cancel-in-progress: true # cancel previous job runs for the same branch jobs: - e2e-test: + check-external-pr: runs-on: ubuntu-latest + if: github.event_name == 'pull_request' steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version-file: go.mod - - - name: Install dependencies - run: go mod tidy - - - name: Create kind cluster - uses: helm/kind-action@v1 - with: - cluster_name: onepassword-operator-test-e2e - - # install cli to interact with item in 1Password to update/read using `testhelper/op` package - - name: Install 1Password CLI - uses: 1password/install-cli-action@v2 - with: - version: 2.32.0 - - - name: Create '1password-credentials.json' file - env: - OP_CONNECT_CREDENTIALS: ${{ secrets.OP_CONNECT_CREDENTIALS }} + - name: Check if PR is from external contributor run: | - echo "$OP_CONNECT_CREDENTIALS" > 1password-credentials.json + if [ "${{ github.event.pull_request.head.repo.full_name }}" != "${{ github.repository }}" ]; then + echo "❌ External PR detected. This workflow requires approval from a maintainer." + echo "Please ask a maintainer to run '/ok-to-test' command to trigger the fork workflow." + exit 1 + fi + echo "✅ Internal PR detected. Proceeding with tests." - - name: Run E2E tests - run: make test-e2e - env: - OP_CONNECT_TOKEN: ${{ secrets.OP_CONNECT_TOKEN }} - OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} + e2e-test: + needs: check-external-pr + if: always() && (needs.check-external-pr.result == 'success' || github.event_name != 'pull_request') + uses: ./.github/workflows/e2e-tests.yml + secrets: + OP_CONNECT_CREDENTIALS: ${{ secrets.OP_CONNECT_CREDENTIALS }} + OP_CONNECT_TOKEN: ${{ secrets.OP_CONNECT_TOKEN }} + OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 71724cf..e784e85 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,10 +11,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Clone the code - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version-file: go.mod