From 82e84f35a8b437486e8d9001c75259567e5a41fa Mon Sep 17 00:00:00 2001 From: d3adb5 Date: Sun, 2 Apr 2023 06:36:48 -0700 Subject: [PATCH 1/4] ci: simplify and refactor integration workflow Simplify the continuous integration workflow by renaming it and making most of the jobs run in parallel. Additionally, the workflow runs on a GitHub hosted runner instead of the Single Node OpenShift runner. --- .github/workflows/ci.yaml | 93 ++++++++++++++++++++++++++ .github/workflows/pull_request.yaml | 100 ---------------------------- 2 files changed, 93 insertions(+), 100 deletions(-) create mode 100644 .github/workflows/ci.yaml delete mode 100644 .github/workflows/pull_request.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 00000000..e076068e --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,93 @@ +name: CI + +on: + pull_request_target: + branches: + - master + paths-ignore: + - 'README.md' + - 'LICENSE' + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + timeout-minutes: 5 + + if: "! contains(toJSON(github.event.commits.*.message), '[skip-ci]')" + + steps: + - uses: actions/checkout@v3 + - uses: azure/setup-helm@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + - run: helm lint application + + unittest: + name: Unit Tests + runs-on: ubuntu-latest + timeout-minutes: 5 + + if: "! contains(toJSON(github.event.commits.*.message), '[skip-ci]')" + + steps: + - uses: actions/checkout@v3 + - uses: d3adb5/helm-unittest-action@v2 + with: + charts: application + + dry-run: + name: Install Dry Run + runs-on: ubuntu-latest + timeout-minutes: 10 + + if: "! contains(toJSON(github.event.commits.*.message), '[skip-ci]')" + + steps: + - uses: actions/checkout@v3 + - uses: helm/kind-action@v1.5.0 + - uses: azure/setup-helm@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + - run: | + helm install --debug --dry-run test-release application \ + -f application/values-test.yaml + + notify: + name: Notify Results + runs-on: ubuntu-latest + timeout-minutes: 5 + needs: [lint, unittest, dry-run] + if: always() && ! contains(toJSON(github.event.commits.*.message), '[skip-ci]') + + + steps: + - id: workflow + name: Compute workflow status + run: | + if [ "${{ contains(needs.*.result, 'failure') }}" = "true" ]; then + echo "status=failure" >> "$GITHUB_OUTPUT" + else + echo "status=success" >> "$GITHUB_OUTPUT" + fi + + - name: Comment on PR + uses: mshick/add-pr-comment@v2 + with: + repo-token: ${{ secrets.STAKATER_GITHUB_TOKEN }} + status: ${{ steps.workflow.outputs.status }} + message-success: >- + @${{ github.actor }} Your PR has passed the status checks! :tada: + message-failure: >- + @${{ github.actor }} Yikes! You better fix your PR before anyone + else finds out! It seems some status checks have failed. + allow-repeats: false + + - name: Notify Slack + uses: 8398a7/action-slack@v3 + if: always() + with: + status: ${{ steps.workflow.outputs.status }} + fields: repo,author,action,eventName,ref,workflow + env: + SLACK_WEBHOOK_URL: ${{ secrets.STAKATER_DELIVERY_SLACK_WEBHOOK }} diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml deleted file mode 100644 index 78f5592d..00000000 --- a/.github/workflows/pull_request.yaml +++ /dev/null @@ -1,100 +0,0 @@ -name: Pull Request - -on: - pull_request_target: - branches: - - master - paths-ignore: - - 'README.md' - - 'LICENSE' - -env: - CHART_NAME: "application" - -jobs: - build: - name: Build - if: "! contains(toJSON(github.event.commits.*.message), '[skip-ci]')" - runs-on: sno2 - - steps: - - - name: Check out code - uses: actions/checkout@v3 - with: - fetch-depth: 0 - ref: ${{github.event.pull_request.head.sha}} - - # Set Up Helm - - name: Set up Helm - uses: azure/setup-helm@v3 - with: - version: v3.8.2 - - # Lint - - name: Helm Lint - run: | - helm lint ${CHART_NAME} - - - name: Install kubectl - uses: azure/setup-kubectl@v3 - with: - version: v1.26.0 - - - name: Install tilt - run: curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash - - - name: Install CLI tools from OpenShift Mirror - uses: redhat-actions/openshift-tools-installer@v1 - with: - oc: "4" - - # This is used to setup kubeconfig, required by Tilt - - name: Login to cluster - run: oc login --token=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) --server=https://kubernetes.default.svc --insecure-skip-tls-verify=true - - # This is required for adding ghcr helm registry - - name: Login to Container Registry - uses: docker/login-action@v2 - with: - registry: ghcr.io/stakater - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Tilt up - run: tilt ci --timeout 5m0s - - # Dry run to ensure that manifests are generated successfully - - name: Dry Run Chart - run: | - helm install ${CHART_NAME} ${CHART_NAME} -f ${CHART_NAME}/values-test.yaml -n stakater-chart-pipeline-test --dry-run --debug - - - name: Tilt down - if: always() - run: tilt down --delete-namespaces --file ./Tiltfile-delete - - - name: Comment on PR - uses: mshick/add-pr-comment@v2 - env: - GITHUB_TOKEN: ${{ secrets.STAKATER_GITHUB_TOKEN }} - with: - message-success: '@${{ github.actor }} validation successful`' - message-failure: '@${{ github.actor }} Yikes! You better fix it before anyone else finds out! [Build](https://github.com/${{ github.repository }}/commit/${{ github.event.pull_request.head.sha }}/checks) has Failed!' - allow-repeats: false - - - name: Notify Slack - uses: 8398a7/action-slack@v3 - if: always() # Pick up events even if the job fails or is canceled. - with: - status: ${{ job.status }} - fields: repo,author,action,eventName,ref,workflow - env: - SLACK_WEBHOOK_URL: ${{ secrets.STAKATER_DELIVERY_SLACK_WEBHOOK }} - - unittest: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: d3adb5/helm-unittest-action@v2 - with: - charts: application From 0810628f35c1cfb9782d8fbd2d0d766756a5158d Mon Sep 17 00:00:00 2001 From: d3adb5 Date: Sun, 2 Apr 2023 08:11:42 -0700 Subject: [PATCH 2/4] cd: simplify delivery workflow to avoid repetition Simplify the CD workflow by invoking a CI build instead of reproducing CI steps on it, as well as splitting the remaining part of the workflow into multiple jobs. --- .github/workflows/cd.yaml | 120 ++++++++++++++++++++++++++ .github/workflows/ci.yaml | 1 + .github/workflows/push.yaml | 168 ------------------------------------ 3 files changed, 121 insertions(+), 168 deletions(-) create mode 100644 .github/workflows/cd.yaml delete mode 100644 .github/workflows/push.yaml diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml new file mode 100644 index 00000000..b50e5514 --- /dev/null +++ b/.github/workflows/cd.yaml @@ -0,0 +1,120 @@ +name: CD + +concurrency: + group: push_on_master + cancel-in-progress: false + +on: + push: + branches: + - master + paths-ignore: + - 'README.md' + - 'LICENSE' + +env: + CHART_NAME: "application" + +jobs: + call-ci-workflow: + uses: ./.github/workflows/ci.yaml + secrets: inherit + + publish: + name: Publish Chart + runs-on: ubuntu-latest + timeout-minutes: 5 + needs: [call-ci-workflow] + + steps: + - uses: actions/checkout@v3 + with: + persist-credentials: false + + - name: Generate New Tag + id: generate_tag + uses: anothrNick/github-tag-action@1.61.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + WITH_V: false + DEFAULT_BUMP: patch + DRY_RUN: true + + - name: Update chart version + env: + VERSION: ${{ steps.generate_tag.outputs.new_tag }} + run: | + make bump-chart + + - name: Publish Helm chart + uses: stefanprodan/helm-gh-pages@master + with: + branch: master + repository: stakater-charts + target_dir: docs + token: ${{ secrets.STAKATER_GITHUB_TOKEN }} + charts_dir: . + charts_url: https://stakater.github.io/stakater-charts + owner: stakater + linting: off + commit_username: stakater-user + commit_email: stakater@gmail.com + + bump-version: + name: Bump Version + runs-on: ubuntu-latest + timeout-minutes: 5 + needs: [publish] + + steps: + - uses: actions/checkout@v3 + with: + persist-credentials: false + fetch-depth: 0 + + - name: Commit files + run: | + git config --local user.email "stakater@gmail.com" + git config --local user.name "stakater-user" + git status + git add application/Chart.yaml + git commit -m "[skip-ci] Update artifacts" + + - name: Push changes + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.STAKATER_GITHUB_TOKEN }} + branch: ${{ inputs.RELEASE_BRANCH }} + + - name: Push latest tag + uses: anothrNick/github-tag-action@1.61.0 + env: + GITHUB_TOKEN: ${{ secrets.STAKATER_GITHUB_TOKEN }} + WITH_V: true + DEFAULT_BUMP: patch + + notify: + name: Notify Results + runs-on: ubuntu-latest + timeout-minutes: 5 + needs: [publish, bump-version] + if: always() + + steps: + - id: workflow + name: Compute workflow status + run: | + if [ "${{ contains(needs.*.result, 'failure') }}" = "true" ]; then + echo "status=failure" >> "$GITHUB_OUTPUT" + else + echo "status=success" >> "$GITHUB_OUTPUT" + fi + + - name: Notify Slack + uses: 8398a7/action-slack@v3 + if: always() + with: + status: ${{ steps.workflow.outputs.status }} + fields: repo,author,action,eventName,ref,workflow + env: + SLACK_WEBHOOK_URL: ${{ secrets.STAKATER_DELIVERY_SLACK_WEBHOOK }} diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e076068e..2459e697 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,6 +1,7 @@ name: CI on: + workflow_call: {} pull_request_target: branches: - master diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml deleted file mode 100644 index a521dc9a..00000000 --- a/.github/workflows/push.yaml +++ /dev/null @@ -1,168 +0,0 @@ -name: Push - -concurrency: - group: push_on_master - cancel-in-progress: false - -on: - push: - branches: - - master - paths-ignore: - - 'README.md' - - 'LICENSE' - -env: - CHART_NAME: "application" - -jobs: - helm-dry-run: - name: helm-dry-run - if: "! contains(toJSON(github.event.commits.*.message), '[skip-ci]')" - runs-on: sno2 - - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token - fetch-depth: 0 # otherwise, you will fail to push refs to dest repo - - # Set Up Helm - - name: Set up Helm - uses: azure/setup-helm@v3 - with: - version: v3.8.2 - - # Lint - - name: Helm Lint - run: | - helm lint ${CHART_NAME} - - - name: Install kubectl - uses: azure/setup-kubectl@v3 - with: - version: v1.26.0 - - - name: Install tilt - run: curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash - - - name: Install CLI tools from OpenShift Mirror - uses: redhat-actions/openshift-tools-installer@v1 - with: - oc: "4" - - # This is used to setup kubeconfig, required by Tilt - - name: Login to cluster - run: oc login --token=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) --server=https://kubernetes.default.svc --insecure-skip-tls-verify=true - - # This is required for adding ghcr helm registry - - name: Login to Container Registry - uses: docker/login-action@v2 - with: - registry: ghcr.io/stakater - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Tilt up - run: tilt ci --timeout 5m0s - - # Dry run to ensure that manifests are generated successfully - - name: Dry Run Chart - run: | - helm install ${CHART_NAME} ${CHART_NAME} -f ${CHART_NAME}/values-test.yaml -n stakater-chart-pipeline-test --dry-run --debug - - - name: Tilt down - if: always() - run: tilt down --delete-namespaces --file ./Tiltfile-delete - - - name: Notify Slack - uses: 8398a7/action-slack@v3 - if: failure() # Pick up events only if the job fails - with: - status: ${{ job.status }} - fields: repo,author,action,eventName,ref,workflow - env: - SLACK_WEBHOOK_URL: ${{ secrets.STAKATER_DELIVERY_SLACK_WEBHOOK }} - - push-changes: - runs-on: ubuntu-latest - needs: - - helm-dry-run - - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token - fetch-depth: 0 # otherwise, you will fail to push refs to dest repo - - # Generate tag for chart without "v" prefix - - name: Generate Tag - id: generate_tag - uses: anothrNick/github-tag-action@1.61.0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - WITH_V: false - DEFAULT_BUMP: patch - DRY_RUN: true - - # Update chart tag to the latest semver tag - - name: Update Chart Version - env: - VERSION: ${{ steps.generate_tag.outputs.new_tag }} - run: | - make bump-chart - - # Set Up Helm - - name: Set up Helm - uses: azure/setup-helm@v3 - with: - version: v3.8.2 - - # Publish helm chart - - name: Publish Helm chart - uses: stefanprodan/helm-gh-pages@master - with: - branch: master - repository: stakater-charts - target_dir: docs - token: ${{ secrets.STAKATER_GITHUB_TOKEN }} - charts_dir: . - charts_url: https://stakater.github.io/stakater-charts - owner: stakater - linting: off - commit_username: stakater-user - commit_email: stakater@gmail.com - - # Commit back changes - - name: Commit files - run: | - git config --local user.email "stakater@gmail.com" - git config --local user.name "stakater-user" - git status - git add application/Chart.yaml - git commit -m "[skip-ci] Update artifacts" - - # Push Chart.yaml with Updated Version - - name: Push changes - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.STAKATER_GITHUB_TOKEN }} - branch: ${{ inputs.RELEASE_BRANCH }} - - - name: Push Latest Tag - uses: anothrNick/github-tag-action@1.61.0 - env: - GITHUB_TOKEN: ${{ secrets.STAKATER_GITHUB_TOKEN }} - WITH_V: true - DEFAULT_BUMP: patch - - - name: Notify Slack - uses: 8398a7/action-slack@v3 - if: always() # Pick up events even if the job fails or is canceled. - with: - status: ${{ job.status }} - fields: repo,author,action,eventName,ref,workflow - env: - SLACK_WEBHOOK_URL: ${{ secrets.STAKATER_DELIVERY_SLACK_WEBHOOK }} From 645165f7d05538f65224b19c727ae5520f71fe7f Mon Sep 17 00:00:00 2001 From: d3adb5 Date: Sun, 2 Apr 2023 07:09:02 -0700 Subject: [PATCH 3/4] chore: remove tiltfiles Remove the Tiltfile and Tiltfile-delete files, since Tilt is no longer executed in CI. This is being done in a separate commit so that should Tilt be re-introduced, the files can be restored with a simple revert. --- Tiltfile | 44 -------------------------------------------- Tiltfile-delete | 41 ----------------------------------------- 2 files changed, 85 deletions(-) delete mode 100644 Tiltfile delete mode 100644 Tiltfile-delete diff --git a/Tiltfile b/Tiltfile deleted file mode 100644 index d0825e0a..00000000 --- a/Tiltfile +++ /dev/null @@ -1,44 +0,0 @@ -load('ext://helm_resource', 'helm_resource', 'helm_repo') -load('ext://namespace', 'namespace_create', 'namespace_inject') - -settings = read_json('tilt-settings-sno3.json', default={}) - -allow_k8s_contexts(k8s_context()) # disable check - -# Add Helm repos -helm_repo('stakater', 'https://stakater.github.io/stakater-charts') -helm_repo('sealed-secrets', 'https://bitnami-labs.github.io/sealed-secrets') - -# Install IMC -imc_namespace = "stakater-ingress-monitor-controller" -namespace_create(imc_namespace) -helm_resource('imc', 'oci://ghcr.io/stakater/charts/ingress-monitor-controller', namespace=imc_namespace,flags=['--set','developmentMode=true']) - -# Install Forecastle -forecastle_namespace = "stakater-forecastle" -namespace_create(forecastle_namespace) -helm_resource('forecastle', 'stakater/forecastle', namespace=forecastle_namespace, resource_deps=["stakater"]) - -# Install SealedSecrets -sealedsecrets_namespace = "sealed-secrets" -namespace_create(sealedsecrets_namespace) -helm_resource('sealedsecrets', 'sealed-secrets/sealed-secrets', namespace=sealedsecrets_namespace, flags=['--set', 'podSecurityContext.enabled=false','--set', 'containerSecurityContext.enabled=false'], resource_deps=["sealed-secrets"]) - -# Install ExternalSecrets -externalsecrets_namespace = "external-secrets-operator" -namespace_create(externalsecrets_namespace) -local_resource( - 'external-secrets-operator', - cmd='helm install external-secrets-operator -n external-secrets-operator oci://ghcr.io/stakater/charts/external-secrets-operator --version=0.0.2 --set operator.installPlanApproval=Automatic --set securityContext.runAsUser="" --set securityContext.fsGroup=""' - ) - -# Install grafana-operator -grafana_namespace = "grafana-operator" -namespace_create(grafana_namespace) -local_resource( - 'grafana-operator', - cmd='helm install grafana-operator -n grafana-operator oci://ghcr.io/stakater/charts/grafana-operator --version=0.0.1 --set operator.installPlanApproval=Automatic' - ) - -# Install cert-manager -# it exists already diff --git a/Tiltfile-delete b/Tiltfile-delete deleted file mode 100644 index f2e3fd32..00000000 --- a/Tiltfile-delete +++ /dev/null @@ -1,41 +0,0 @@ -include('Tiltfile') - -def delete_grafana_operator(): - print('Deleting grafana operator') - local('helm uninstall grafana-operator -n grafana-operator') - -def delete_external_secrets_operator(): - print('Deleting external-secrets operator') - local('helm uninstall external-secrets-operator -n external-secrets-operator') - -def delete_imc_crds(): - print('Deleting imc crds') - local('oc get crds -o name | grep \'endpointmonitor\\.stakater\\.com\' | xargs -r -n 1 oc delete') - -def delete_forecastle_crds(): - print('Deleting forecastle crds') - local('oc get crds -o name | grep \'forecastle\\.stakater\\.com\' | xargs -r -n 1 oc delete') - -def delete_ss_crds(): - print('Deleting sealedsecrets crds') - local('oc get crds -o name | grep \'bitnami\\.com\' | xargs -r -n 1 oc delete') - -def delete_es_crds(): - print('Deleting externalsecrets crds') - local('oc get crds -o name | grep \'external-secrets\\.io\' | xargs -r -n 1 oc delete') - -def delete_grafana_crds(): - print('Deleting crds') - local('oc get crds -o name | grep \'grafanas\\.integreatly\\.org\' | xargs -r -n 1 oc delete') - local('oc get crds -o name | grep \'grafanadashboards\\.integreatly\\.org\' | xargs -r -n 1 oc delete') - local('oc get crds -o name | grep \'grafanadatasources\\.integreatly\\.org\' | xargs -r -n 1 oc delete') - local('oc get crds -o name | grep \'grafanafolders\\.integreatly\\.org\' | xargs -r -n 1 oc delete') - local('oc get crds -o name | grep \'grafananotificationchannels\\.integreatly\\.org\' | xargs -r -n 1 oc delete') - -delete_grafana_operator() -delete_external_secrets_operator() -delete_imc_crds() -delete_forecastle_crds() -delete_ss_crds() -delete_es_crds() -delete_grafana_crds() \ No newline at end of file From d284f500a5d1bf84964a2f6561550ecbc2ece381 Mon Sep 17 00:00:00 2001 From: d3adb5 Date: Sun, 2 Apr 2023 08:17:50 -0700 Subject: [PATCH 4/4] ci: add input to skip sending slack notification Add an input to the CI workflow to allow skipping sending a Slack notification, as it might not be necessary. --- .github/workflows/cd.yaml | 2 ++ .github/workflows/ci.yaml | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index b50e5514..8f235b43 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -19,6 +19,8 @@ jobs: call-ci-workflow: uses: ./.github/workflows/ci.yaml secrets: inherit + with: + skip-slack-notification: true publish: name: Publish Chart diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 2459e697..3c961f0c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,7 +1,13 @@ name: CI on: - workflow_call: {} + workflow_call: + inputs: + skip-slack-notification: + description: Whether to skip sending a notification to Slack. + required: true + type: boolean + pull_request_target: branches: - master @@ -86,7 +92,7 @@ jobs: - name: Notify Slack uses: 8398a7/action-slack@v3 - if: always() + if: always() && ! inputs.skip-slack-notification with: status: ${{ steps.workflow.outputs.status }} fields: repo,author,action,eventName,ref,workflow