From 5b352c5d40f052e946fa6d4c82210ad3ede59fca Mon Sep 17 00:00:00 2001 From: Kyle Squizzato Date: Fri, 18 Oct 2024 13:53:11 -0700 Subject: [PATCH 1/4] Add access checks prior to checking our PRs Ensure only users with write permissions can run CI Signed-off-by: Kyle Squizzato --- .github/workflows/build_test.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 52678072..fd61eaa7 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -12,6 +12,7 @@ on: paths-ignore: - 'config/**' - '**.md' + - '.github/**' push: tags: - '*' @@ -32,6 +33,22 @@ jobs: clustername: ${{ steps.vars.outputs.clustername }} pr: ${{ steps.pr.outputs.result }} steps: + - name: Get User Permissions + id: checkAccess + uses: actions-cool/check-user-permission@v2 + with: + require: write + username: ${{ github.triggering_actor }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Check User Permissions + if: steps.checkAccess.outputs.require-result == 'false' + run: | + echo "${{ github.triggering_actor }} does not have permissions on this repo." + echo "Current permission level: ${{ steps.checkAccess.outputs.user-permission }}" + echo "Job originally triggered by: ${{ github.actor }}" + echo "This job must be triggered by a user with proper permissions, if you have opened a PR and lack permissions please ask a repo collaborator to re-run this job on your behalf." + exit 1 - name: Get PR ref uses: actions/github-script@v6 id: pr From 916b428ca5544746deba9717d0e775538713cfb9 Mon Sep 17 00:00:00 2001 From: Kyle Squizzato Date: Tue, 29 Oct 2024 12:11:25 -0400 Subject: [PATCH 2/4] Break e2e tests into own workflow, use pull_request for all workflows This patch breaks the e2e test and build workflows apart making it so that all workflows return to using 'pull_request' to avoid any security issues and other frustrations surrounding 'pull_request_target' We now have 2 workflow files, one for build and unit tests which uses 'pull_request' and one for e2e tests. The e2e tests require secret population and must be created on branch to run, they also require the 'test e2e' label to prevent uneccessary execution. Signed-off-by: Kyle Squizzato --- .github/workflows/build_unit_test.yml | 50 ++++++++ .../{build_test.yml => e2e_test.yml} | 114 ++++++------------ 2 files changed, 85 insertions(+), 79 deletions(-) create mode 100644 .github/workflows/build_unit_test.yml rename .github/workflows/{build_test.yml => e2e_test.yml} (64%) diff --git a/.github/workflows/build_unit_test.yml b/.github/workflows/build_unit_test.yml new file mode 100644 index 00000000..0bb660a9 --- /dev/null +++ b/.github/workflows/build_unit_test.yml @@ -0,0 +1,50 @@ +name: Build and Unit Tests +on: + pull_request: + types: + - labeled + - opened + - synchronize + - reopened + branches: + - main + - release-* + paths-ignore: + - 'config/**' + - '**.md' + push: + tags: + - '*' + +env: + GO_VERSION: '1.22' + +jobs: + build: + concurrency: + group: ${{ github.head_ref || github.run_id }} + cancel-in-progress: true + name: Build and Unit Test + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: ${{ env.GO_VERSION }} + cache: false + - name: Lint + uses: golangci/golangci-lint-action@v6 + with: + args: --timeout 10m0s + - name: Verify all generated pieces are up-to-date + run: make generate-all && git add -N . && git diff --exit-code + - name: Unit tests + run: | + make test + - name: Build HMC controller image + run: | + make docker-build \ No newline at end of file diff --git a/.github/workflows/build_test.yml b/.github/workflows/e2e_test.yml similarity index 64% rename from .github/workflows/build_test.yml rename to .github/workflows/e2e_test.yml index fd61eaa7..18be6857 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/e2e_test.yml @@ -1,6 +1,6 @@ -name: CI +name: E2E Tests on: - pull_request_target: + pull_request: types: - labeled - opened @@ -12,7 +12,6 @@ on: paths-ignore: - 'config/**' - '**.md' - - '.github/**' push: tags: - '*' @@ -22,62 +21,25 @@ env: REGISTRY_REPO: 'oci://ghcr.io/mirantis/hmc/charts-ci' jobs: - build: + push: concurrency: - group: build-${{ github.head_ref || github.run_id }} + group: push-${{ github.head_ref || github.run_id }} cancel-in-progress: true - name: Build and Unit Test + name: Push Images and Charts to GHCR runs-on: ubuntu-latest outputs: version: ${{ steps.vars.outputs.version }} clustername: ${{ steps.vars.outputs.clustername }} - pr: ${{ steps.pr.outputs.result }} steps: - - name: Get User Permissions - id: checkAccess - uses: actions-cool/check-user-permission@v2 - with: - require: write - username: ${{ github.triggering_actor }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Check User Permissions - if: steps.checkAccess.outputs.require-result == 'false' - run: | - echo "${{ github.triggering_actor }} does not have permissions on this repo." - echo "Current permission level: ${{ steps.checkAccess.outputs.user-permission }}" - echo "Job originally triggered by: ${{ github.actor }}" - echo "This job must be triggered by a user with proper permissions, if you have opened a PR and lack permissions please ask a repo collaborator to re-run this job on your behalf." - exit 1 - - name: Get PR ref - uses: actions/github-script@v6 - id: pr - with: - script: | - const { data: pullRequest } = await github.rest.pulls.get({ - ...context.repo, - pull_number: context.payload.pull_request.number, - }); - return pullRequest - name: Checkout repository uses: actions/checkout@v4 with: - ref: ${{fromJSON(steps.pr.outputs.result).merge_commit_sha}} fetch-depth: 0 - name: Setup Go uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} cache: false - - name: Lint - uses: golangci/golangci-lint-action@v6 - with: - args: --timeout 10m0s - - name: Verify all generated pieces are up-to-date - run: make generate-all && git add -N . && git diff --exit-code - - name: Unit tests - run: | - make test - name: Set up Buildx uses: docker/setup-buildx-action@v3 - name: Login to GHCR @@ -92,7 +54,8 @@ jobs: GIT_VERSION=$(git describe --tags --always) echo "version=${GIT_VERSION:1}" >> $GITHUB_OUTPUT echo "clustername=ci-$(date +%s | cut -b6-10)" >> $GITHUB_OUTPUT - - name: Build and push HMC controller image + - name: Push HMC Controller Image to GHCR + if: uses: docker/build-push-action@v6 with: build-args: | @@ -104,36 +67,35 @@ jobs: push: true cache-from: type=gha cache-to: type=gha,mode=max - - name: Prepare and push HMC template charts + - name: Prepare and push HMC template charts to GHCR run: | make hmc-chart-release make helm-push controller-e2etest: - name: E2E Controller + name: Controller runs-on: ubuntu-latest - needs: build + if: ${{ contains( github.event.pull_request.labels.*.name, 'test e2e') }} + needs: push concurrency: group: controller-${{ github.head_ref || github.run_id }} cancel-in-progress: true outputs: - clustername: ${{ needs.build.outputs.clustername }} - version: ${{ needs.build.outputs.version }} - pr: ${{ needs.build.outputs.pr }} + clustername: ${{ needs.push.outputs.clustername }} + version: ${{ needs.push.outputs.version }} steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - ref: ${{fromJSON(needs.build.outputs.pr).merge_commit_sha}} - name: Setup kubectl uses: azure/setup-kubectl@v4 - name: Run E2E tests env: GINKGO_LABEL_FILTER: 'controller' - MANAGED_CLUSTER_NAME: ${{ needs.build.outputs.clustername }} - IMG: 'ghcr.io/mirantis/hmc/controller-ci:${{ needs.build.outputs.version }}' - VERSION: ${{ needs.build.outputs.version }} + MANAGED_CLUSTER_NAME: ${{ needs.push.outputs.clustername }} + IMG: 'ghcr.io/mirantis/hmc/controller-ci:${{ needs.push.outputs.version }}' + VERSION: ${{ needs.push.outputs.version }} run: | make test-e2e - name: Archive test results @@ -145,17 +107,16 @@ jobs: test/e2e/*.log provider-cloud-e2etest: - name: E2E Cloud Providers + name: Cloud Providers runs-on: ubuntu-latest if: ${{ contains( github.event.pull_request.labels.*.name, 'test e2e') }} - needs: build + needs: push concurrency: group: cloud-${{ github.head_ref || github.run_id }} cancel-in-progress: true outputs: - clustername: ${{ needs.build.outputs.clustername }} - version: ${{ needs.build.outputs.version }} - pr: ${{ needs.build.outputs.pr }} + clustername: ${{ needs.push.outputs.clustername }} + version: ${{ needs.push.outputs.version }} env: AWS_REGION: us-west-2 AWS_ACCESS_KEY_ID: ${{ secrets.CI_AWS_ACCESS_KEY_ID }} @@ -170,7 +131,6 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - ref: ${{fromJSON(needs.build.outputs.pr).merge_commit_sha}} - name: Setup Go uses: actions/setup-go@v5 with: @@ -181,9 +141,9 @@ jobs: - name: Run E2E tests env: GINKGO_LABEL_FILTER: 'provider:cloud' - MANAGED_CLUSTER_NAME: ${{ needs.build.outputs.clustername }} - IMG: 'ghcr.io/mirantis/hmc/controller-ci:${{ needs.build.outputs.version }}' - VERSION: ${{ needs.build.outputs.version }} + MANAGED_CLUSTER_NAME: ${{ needs.push.outputs.clustername }} + IMG: 'ghcr.io/mirantis/hmc/controller-ci:${{ needs.push.outputs.version }}' + VERSION: ${{ needs.push.outputs.version }} run: | make test-e2e - name: Archive test results @@ -195,17 +155,16 @@ jobs: test/e2e/*.log provider-onprem-e2etest: - name: E2E On-Prem Providers + name: On-Prem Providers runs-on: self-hosted if: ${{ contains( github.event.pull_request.labels.*.name, 'test e2e') }} - needs: build + needs: push concurrency: group: onprem-${{ github.head_ref || github.run_id }} cancel-in-progress: true outputs: - clustername: ${{ needs.build.outputs.clustername }} - version: ${{ needs.build.outputs.version }} - pr: ${{ needs.build.outputs.pr }} + clustername: ${{ needs.push.outputs.clustername }} + version: ${{ needs.push.outputs.version }} env: VSPHERE_USER: ${{ secrets.CI_VSPHERE_USER }} VSPHERE_PASSWORD: ${{ secrets.CI_VSPHERE_PASSWORD }} @@ -224,7 +183,6 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - ref: ${{fromJSON(needs.build.outputs.pr).merge_commit_sha}} - name: Setup Go uses: actions/setup-go@v5 with: @@ -234,9 +192,9 @@ jobs: - name: Run E2E tests env: GINKGO_LABEL_FILTER: 'provider:onprem' - MANAGED_CLUSTER_NAME: ${{ needs.build.outputs.clustername }} - IMG: 'ghcr.io/mirantis/hmc/controller-ci:${{ needs.build.outputs.version }}' - VERSION: ${{ needs.build.outputs.version }} + MANAGED_CLUSTER_NAME: ${{ needs.push.outputs.clustername }} + IMG: 'ghcr.io/mirantis/hmc/controller-ci:${{ needs.push.outputs.version }}' + VERSION: ${{ needs.push.outputs.version }} run: | make test-e2e - name: Archive test results @@ -250,21 +208,19 @@ jobs: cleanup: name: Cleanup needs: - - build + - push - provider-cloud-e2etest runs-on: ubuntu-latest - if: ${{ always() && !contains(needs.provider-cloud-e2etest.result, 'skipped') && contains(needs.build.result, 'success') }} + if: ${{ always() && !contains(needs.provider-cloud-e2etest.result, 'skipped') && contains(needs.push.result, 'success') }} timeout-minutes: 15 outputs: - clustername: ${{ needs.build.outputs.clustername }} - version: ${{ needs.build.outputs.version }} - pr: ${{ needs.build.outputs.pr }} + clustername: ${{ needs.push.outputs.clustername }} + version: ${{ needs.push.outputs.version }} steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - ref: ${{fromJSON(needs.build.outputs.pr).merge_commit_sha}} - name: Setup Go uses: actions/setup-go@v5 with: @@ -279,7 +235,7 @@ jobs: AZURE_TENANT_ID: ${{ secrets.CI_AZURE_TENANT_ID }} AZURE_CLIENT_ID: ${{ secrets.CI_AZURE_CLIENT_ID }} AZURE_CLIENT_SECRET: ${{ secrets.CI_AZURE_CLIENT_SECRET }} - CLUSTER_NAME: '${{ needs.build.outputs.clustername }}' + CLUSTER_NAME: '${{ needs.push.outputs.clustername }}' run: | make dev-aws-nuke make dev-azure-nuke From 6eb266b9cad9b9e69816a99669494c2daa82133d Mon Sep 17 00:00:00 2001 From: Kyle Squizzato Date: Thu, 31 Oct 2024 08:28:27 -0700 Subject: [PATCH 3/4] Ensure all e2e_test workflows only run when labeled Signed-off-by: Kyle Squizzato --- .github/workflows/e2e_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/e2e_test.yml b/.github/workflows/e2e_test.yml index 18be6857..84b5e5c5 100644 --- a/.github/workflows/e2e_test.yml +++ b/.github/workflows/e2e_test.yml @@ -27,6 +27,7 @@ jobs: cancel-in-progress: true name: Push Images and Charts to GHCR runs-on: ubuntu-latest + if: ${{ contains( github.event.pull_request.labels.*.name, 'test e2e') }} outputs: version: ${{ steps.vars.outputs.version }} clustername: ${{ steps.vars.outputs.clustername }} From 50faa9977031b9716b6c371b18143c4671d5444f Mon Sep 17 00:00:00 2001 From: Kyle Squizzato Date: Thu, 31 Oct 2024 08:39:12 -0700 Subject: [PATCH 4/4] Only run E2E Push job if Build completes Signed-off-by: Kyle Squizzato --- .../{e2e_test.yml => build_test.yml} | 42 +++++++++++++--- .github/workflows/build_unit_test.yml | 50 ------------------- 2 files changed, 36 insertions(+), 56 deletions(-) rename .github/workflows/{e2e_test.yml => build_test.yml} (89%) delete mode 100644 .github/workflows/build_unit_test.yml diff --git a/.github/workflows/e2e_test.yml b/.github/workflows/build_test.yml similarity index 89% rename from .github/workflows/e2e_test.yml rename to .github/workflows/build_test.yml index 84b5e5c5..429ce805 100644 --- a/.github/workflows/e2e_test.yml +++ b/.github/workflows/build_test.yml @@ -1,4 +1,4 @@ -name: E2E Tests +name: CI on: pull_request: types: @@ -21,12 +21,42 @@ env: REGISTRY_REPO: 'oci://ghcr.io/mirantis/hmc/charts-ci' jobs: + build: + concurrency: + group: ${{ github.head_ref || github.run_id }} + cancel-in-progress: true + name: Build and Unit Test + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: ${{ env.GO_VERSION }} + cache: false + - name: Lint + uses: golangci/golangci-lint-action@v6 + with: + args: --timeout 10m0s + - name: Verify all generated pieces are up-to-date + run: make generate-all && git add -N . && git diff --exit-code + - name: Unit tests + run: | + make test + - name: Build HMC controller image + run: | + make docker-build + push: concurrency: group: push-${{ github.head_ref || github.run_id }} cancel-in-progress: true - name: Push Images and Charts to GHCR + name: E2E Push Images and Charts to GHCR runs-on: ubuntu-latest + needs: build if: ${{ contains( github.event.pull_request.labels.*.name, 'test e2e') }} outputs: version: ${{ steps.vars.outputs.version }} @@ -74,7 +104,7 @@ jobs: make helm-push controller-e2etest: - name: Controller + name: E2E Controller runs-on: ubuntu-latest if: ${{ contains( github.event.pull_request.labels.*.name, 'test e2e') }} needs: push @@ -108,7 +138,7 @@ jobs: test/e2e/*.log provider-cloud-e2etest: - name: Cloud Providers + name: E2E Cloud Providers runs-on: ubuntu-latest if: ${{ contains( github.event.pull_request.labels.*.name, 'test e2e') }} needs: push @@ -156,7 +186,7 @@ jobs: test/e2e/*.log provider-onprem-e2etest: - name: On-Prem Providers + name: E2E On-Prem Providers runs-on: self-hosted if: ${{ contains( github.event.pull_request.labels.*.name, 'test e2e') }} needs: push @@ -207,7 +237,7 @@ jobs: test/e2e/*.log cleanup: - name: Cleanup + name: E2E Cleanup needs: - push - provider-cloud-e2etest diff --git a/.github/workflows/build_unit_test.yml b/.github/workflows/build_unit_test.yml deleted file mode 100644 index 0bb660a9..00000000 --- a/.github/workflows/build_unit_test.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: Build and Unit Tests -on: - pull_request: - types: - - labeled - - opened - - synchronize - - reopened - branches: - - main - - release-* - paths-ignore: - - 'config/**' - - '**.md' - push: - tags: - - '*' - -env: - GO_VERSION: '1.22' - -jobs: - build: - concurrency: - group: ${{ github.head_ref || github.run_id }} - cancel-in-progress: true - name: Build and Unit Test - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: ${{ env.GO_VERSION }} - cache: false - - name: Lint - uses: golangci/golangci-lint-action@v6 - with: - args: --timeout 10m0s - - name: Verify all generated pieces are up-to-date - run: make generate-all && git add -N . && git diff --exit-code - - name: Unit tests - run: | - make test - - name: Build HMC controller image - run: | - make docker-build \ No newline at end of file