From c48f71054528e69b68122470e459b54f3975234d Mon Sep 17 00:00:00 2001 From: Andreas Salhus Bakseter <141913422+baksetercx@users.noreply.github.com> Date: Fri, 8 Nov 2024 12:13:35 +0100 Subject: [PATCH] Add action for tagging ISS images (#154) --- .../example-build-deploy-dotnet-iss.yml | 187 ++++++++++++++++++ .../workflows/update-starter-workflows.yml | 5 +- README.md | 8 +- iss-tag-push-image/action.yml | 35 ++++ 4 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/example-build-deploy-dotnet-iss.yml create mode 100644 iss-tag-push-image/action.yml diff --git a/.github/workflows/example-build-deploy-dotnet-iss.yml b/.github/workflows/example-build-deploy-dotnet-iss.yml new file mode 100644 index 0000000..4aef74f --- /dev/null +++ b/.github/workflows/example-build-deploy-dotnet-iss.yml @@ -0,0 +1,187 @@ +name: Build and Deploy .NET to ISS + +on: + push: + branches: [too-complicated-to-setup-tests-for-this-so-we-dont] +## Adding a path filter will only trigger the workflow if the files in the path are modified. +## This is very useful if you have a monorepo structure. +## See https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onpushpull_requestpull_request_targetpathspaths-ignore for more information. +## +# paths: +# - 'applications/my-app/**' +## +# pull_request: +# branches: [trunk] + +## This will limit the number of concurrent workflows to 1 per branch. +## +## The parameter `cancel-in-progress` will cancel the previous workflow if a new one is triggered. +## Commenting out `cancel-in-progress` will make the new workflow wait for the previous one to finish. +## +## See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#concurrency for more information. +concurrency: + group: '${{ github.workflow }}-${{ github.ref }}' + cancel-in-progress: true + +env: + APPLICATION_NAME: 'demo-api' + SYSTEM_NAME: 'iss' + HELM_VALUES_PATH: '.github/test/deploy/values.yml' + PROJECT_FILE: '.github/test/src/core-demo-api.csproj' + +jobs: + analyze: + name: Analyze + runs-on: elvia-runner + permissions: + actions: read + contents: read + security-events: write + steps: + - uses: 3lvia/core-github-actions-templates/analyze@trunk + + unit-tests: + name: Unit Tests + runs-on: elvia-runner + permissions: + contents: read + checks: write + issues: read + pull-requests: write + steps: + - uses: 3lvia/core-github-actions-templates/unittest@trunk + with: + test-coverage: 'true' + + integration-tests: + name: Integration Tests + runs-on: elvia-runner + permissions: + contents: read + checks: write + issues: read + pull-requests: write + id-token: write + steps: + - uses: 3lvia/core-github-actions-templates/integrationtest@trunk + with: + system: ${{ env.SYSTEM_NAME }} + + build-scan: + name: Build and Scan + runs-on: elvia-runner + permissions: + actions: read + contents: write + packages: write + pull-requests: write + security-events: write + environment: build + outputs: + image: ${{ steps.build.outputs.image-name }} + steps: + - uses: 3lvia/core-github-actions-templates/build@trunk + id: build + with: + name: ${{ env.APPLICATION_NAME }} + namespace: ${{ env.SYSTEM_NAME }} + project-file: ${{ env.PROJECT_FILE }} + trivy-upload-report: 'true' + trivy-post-comment: 'true' + registry: 'ghcr.io/3lvia' + + push-images: + name: Push images to GCR + needs: [build-scan] + runs-on: 'iss-agent-vm-${{ matrix.environment }}-runner' + permissions: + contents: read + packages: read + strategy: + matrix: + environment: + - dev + - test + - prod + environment: ${{ matrix.environment }} + steps: + - name: Tag image and push to GCR + # On pull requests, only push to dev GCR + if: ${{ github.ref == 'refs/heads/trunk' || (github.event_name == 'pull_request' && matrix.environment == 'dev') }} + uses: 3lvia/core-github-actions-templates/iss-tag-push-image@feat/iss-tag + with: + old-image-name-with-tag: ${{ needs.build-scan.outputs.image }} + new-image-name: 'gcr.io/${{ vars.GC_ISS_PROJECT_ID }}/${{ env.SYSTEM_NAME }}-${{ env.APPLICATION_NAME }}' + + deploy-dev: + name: Deploy Dev + # Require all jobs below to be successful before running this job. + # Any of these (except `push-images`) can be commented out or removed if you want to deploy anyway. + needs: + - analyze + - unit-tests + - integration-tests + - push-images # Never remove this, as it is required for the deployment to work. + runs-on: iss-agent-vm-dev-runner + permissions: + contents: read + id-token: write + packages: read + environment: dev + steps: + - uses: 3lvia/core-github-actions-templates/deploy@trunk + with: + name: ${{ env.APPLICATION_NAME }} + namespace: ${{ env.SYSTEM_NAME }} + environment: 'dev' + helm-values-path: ${{ env.HELM_VALUES_PATH }} + runtime-cloud-provider: 'ISS' + # Will post to the Slack channel of your system if the deployment fails. + # Can be commented out if you don't want this. + slack-channel: '#team-${{ env.SYSTEM_NAME }}-alerts' + + deploy-test: + name: Deploy Test + # Only deploy to test after dev + needs: [deploy-dev] + runs-on: iss-agent-vm-test-runner + permissions: + contents: read + id-token: write + environment: test + # Only on push to trunk + if: github.ref == 'refs/heads/trunk' + steps: + - uses: 3lvia/core-github-actions-templates/deploy@trunk + with: + name: ${{ env.APPLICATION_NAME }} + namespace: ${{ env.SYSTEM_NAME }} + environment: 'test' + helm-values-path: ${{ env.HELM_VALUES_PATH }} + runtime-cloud-provider: 'ISS' + # Will post to the Slack channel of your system if the deployment fails. + # Can be commented out if you don't want this. + slack-channel: '#team-${{ env.SYSTEM_NAME }}-alerts' + + deploy-prod: + name: Deploy Prod + # Only deploy to prod after test + needs: [deploy-test] + runs-on: iss-agent-vm-prod-runner + permissions: + contents: read + id-token: write + environment: prod + # Only on push to trunk + if: github.ref == 'refs/heads/trunk' + steps: + - uses: 3lvia/core-github-actions-templates/deploy@trunk + with: + name: ${{ env.APPLICATION_NAME }} + namespace: ${{ env.SYSTEM_NAME }} + environment: 'prod' + helm-values-path: ${{ env.HELM_VALUES_PATH }} + runtime-cloud-provider: 'ISS' + # Will post to the Slack channel of your system if the deployment fails. + # Can be commented out if you don't want this. + slack-channel: '#team-${{ env.SYSTEM_NAME }}-alerts' diff --git a/.github/workflows/update-starter-workflows.yml b/.github/workflows/update-starter-workflows.yml index d94f025..2f3809f 100644 --- a/.github/workflows/update-starter-workflows.yml +++ b/.github/workflows/update-starter-workflows.yml @@ -61,13 +61,16 @@ jobs: cp "$workflow_path" "$new_workflow_path" sed -i "s/ APPLICATION_NAME: '.*'/ APPLICATION_NAME: ''/g" "$new_workflow_path" - sed -i "s/ SYSTEM_NAME: 'core'/ SYSTEM_NAME: ''/g" "$new_workflow_path" + sed -i "s/ SYSTEM_NAME: '.*'/ SYSTEM_NAME: ''/g" "$new_workflow_path" sed -i "s/ HELM_VALUES_PATH: '.*'/ HELM_VALUES_PATH: '.github\/deploy\/values.yml'/g" "$new_workflow_path" sed -i "s/ PROJECT_FILE: '.*'/ PROJECT_FILE: ''/g" "$new_workflow_path" sed -i "s/# pull_request:/ pull_request:/g" "$new_workflow_path" sed -i 's/# branches:/ branches:/g' "$new_workflow_path" sed -i 's/branches: \[trunk\]/branches: \[$default-branch\]/g' "$new_workflow_path" + # Special case for ISS example + sed -i 's/branches: \[too-complicated-to-setup-tests-for-this-so-we-dont\]/branches: \[$default-branch\]/g' "$new_workflow_path" + # Special case for removing concurrency groups for demo-api-go, since it is deployed twice (go.mod and Dockerfile) perl \ -0777pe "s/ concurrency:\n group: '(dev|test|prod)-(azure|google)--this-block-is-removed-in-final-example-needs-this-to-not-deploy-demo-api-go-simultaneously-in-two-examples'\n//g" \ diff --git a/README.md b/README.md index 6110395..5c570b5 100644 --- a/README.md +++ b/README.md @@ -898,7 +898,12 @@ More permissions might be required depending on the inputs set, see the actions -## Elvia-specific actions + + + + + +## Elvia-specific Actions The below list of actions are specific to Elvia's infrastructure and will not work outside our organization: @@ -906,6 +911,7 @@ The below list of actions are specific to Elvia's infrastructure and will not wo - [SonarCloud](#sonarcloud) - [PlayWright Test](#playwright-test) - [Validate Metrics](#validate-metrics) +- [ISS Tag & Push Image](#iss-tag-push-image) # Development diff --git a/iss-tag-push-image/action.yml b/iss-tag-push-image/action.yml new file mode 100644 index 0000000..b3b7736 --- /dev/null +++ b/iss-tag-push-image/action.yml @@ -0,0 +1,35 @@ +name: 'ISS Tag & Push Image' +description: | + Pulls image from GHCR, re-tags it and pushes it to GCR. + + *Only useful for ISS deployments.* +inputs: + old-image-name-with-tag: + description: 'Name of the Docker image to pull from GHCR, including the tag.' + required: true + new-image-name: + description: 'Name of the Docker image to push to GCR, without the tag.' + required: true + +runs: + using: 'composite' + steps: + - name: Login to GHCR + uses: docker/login-action@v3 + with: + registry: 'ghcr.io' + username: ${{ github.actor }} + password: ${{ github.token }} + + - name: Pull image from GHCR, re-tag and push to GCR + shell: bash + run: | + tag=$(echo "$OLD_IMAGE_NAME_WITH_TAG" | cut -d ':' -f 2) + new_image_name_with_tag="$NEW_IMAGE_NAME:$tag" + + docker pull "$OLD_IMAGE_NAME_WITH_TAG" + docker tag "$OLD_IMAGE_NAME_WITH_TAG" "$new_image_name_with_tag" + docker push "$new_image_name_with_tag" + env: + OLD_IMAGE_NAME_WITH_TAG: ${{ inputs.old-image-name-with-tag }} + NEW_IMAGE_NAME: ${{ inputs.new-image-name }}