diff --git a/.github/workflows/kubernetes.yaml b/.github/workflows/kubernetes.yaml index 7ade37c..2251398 100644 --- a/.github/workflows/kubernetes.yaml +++ b/.github/workflows/kubernetes.yaml @@ -27,6 +27,10 @@ on: description: The repository within Github that holds the version file to deploy via GitOps default: parcelLab/deployment type: string + imageTargets: + required: false + description: If provided, sets targets for as many image builds as targets specified + type: string preScript: required: false description: If provided, runs a script after repo checkout and before the docker image is built. Useful in case that you need to build a package outside of the docker image (and load the artifacts via copy). @@ -120,10 +124,16 @@ on: required: true description: AWS Account ID jobs: - kubernetes: + parallel: environment: ${{ github.event.deployment.payload.env }} - concurrency: ${{ github.event.deployment.payload.env }} + # concurrency: ${{ github.event.deployment.payload.env }} runs-on: ${{ inputs.runner }} + strategy: + matrix: + containerfile_targets: ${{ fromJson(inputs.imageTargets) }} + outputs: + channel-id: ${{ steps.vars.outputs.channel-id }} + version: ${{ steps.vars.outputs.version }} steps: - name: Load deployment variables id: vars @@ -180,8 +190,8 @@ jobs: registry: ${{ inputs.registryHostname }} username: ${{ inputs.registryUsername }} password: ${{ secrets.repoAccessToken }} - - name: Build and push latest version to GitHub - if: inputs.repository_kind == 'github' + - name: Build and push image to GitHub + if: inputs.repository_kind == 'github' && matrix.containerfile_targets == '' uses: docker/build-push-action@v6 with: build-args: | @@ -200,6 +210,27 @@ jobs: ${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}:latest ${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}:${{ steps.vars.outputs.version }} ${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}:${{ github.sha }} + - name: Build and push ${{ matrix.containerfile_targets }} image to GitHub + if: inputs.repository_kind == 'github' && matrix.containerfile_targets != '' + uses: docker/build-push-action@v6 + with: + build-args: | + GITHUB_SHA=${{ github.sha }} + VERSION=${{ steps.vars.outputs.version }} + APP_NAME=${{ github.event.deployment.payload.name }} + ENVIRONMENT=${{ github.event.deployment.payload.env }} + NPM_GITHUB_TOKEN=${{ secrets.npmGithubReadToken }} + cache-from: type=registry,ref=${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }} + cache-to: type=inline + context: ${{ github.event.deployment.payload.container.context }} + file: ${{ github.event.deployment.payload.container.file }} + platforms: linux/amd64 + push: true + tags: | + ${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}:latest + ${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}:${{ steps.vars.outputs.version }} + ${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}:${{ github.sha }} + target: ${{ matrix.containerfile_targets }} - name: Configure AWS credentials if: inputs.repository_kind == 'ecr' uses: aws-actions/configure-aws-credentials@v2 @@ -208,18 +239,25 @@ jobs: aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: eu-central-1 - name: Create ECR repository if it doesn't exist - if: inputs.repository_kind == 'ecr' + if: inputs.repository_kind == 'ecr' && matrix.containerfile_targets == '' run: | aws ecr describe-repositories --repository-names ${{ github.event.deployment.payload.name }} || \ aws ecr create-repository --repository-name ${{ github.event.deployment.payload.name }} LIFECYCLE_POLICY='{"rules":[{"rulePriority":1,"description":"Keep last 500 images","selection":{"tagStatus":"any","countType":"imageCountMoreThan","countNumber":500},"action":{"type":"expire"}}]}' aws ecr put-lifecycle-policy --repository-name ${{ github.event.deployment.payload.name }} --lifecycle-policy-text "$LIFECYCLE_POLICY" + - name: Create ${{ matrix.containerfile_targets }} ECR repository if it doesn't exist + if: inputs.repository_kind == 'ecr' && matrix.containerfile_targets != '' + run: | + aws ecr describe-repositories --repository-names ${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }} || \ + aws ecr create-repository --repository-name ${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }} + LIFECYCLE_POLICY='{"rules":[{"rulePriority":1,"description":"Keep last 500 images","selection":{"tagStatus":"any","countType":"imageCountMoreThan","countNumber":500},"action":{"type":"expire"}}]}' + aws ecr put-lifecycle-policy --repository-name ${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }} --lifecycle-policy-text "$LIFECYCLE_POLICY" - name: Login to Amazon ECR if: inputs.repository_kind == 'ecr' id: login-ecr uses: aws-actions/amazon-ecr-login@v2 - - name: Build and push latest version to ECR - if: inputs.repository_kind == 'ecr' + - name: Build and push image to ECR + if: inputs.repository_kind == 'ecr' && matrix.containerfile_targets == '' uses: docker/build-push-action@v6 with: build-args: | @@ -238,6 +276,32 @@ jobs: ${{ steps.login-ecr.outputs.registry }}/${{ github.event.deployment.payload.name }}:latest ${{ steps.login-ecr.outputs.registry }}/${{ github.event.deployment.payload.name }}:${{ steps.vars.outputs.version }} ${{ steps.login-ecr.outputs.registry }}/${{ github.event.deployment.payload.name }}:${{ github.sha }} + - name: Build and push ${{ matrix.containerfile_targets }} image to ECR + if: inputs.repository_kind == 'ecr' && matrix.containerfile_targets != '' + uses: docker/build-push-action@v6 + with: + build-args: | + GITHUB_SHA=${{ github.sha }} + VERSION=${{ steps.vars.outputs.version }} + APP_NAME=${{ github.event.deployment.payload.name }} + ENVIRONMENT=${{ github.event.deployment.payload.env }} + NPM_GITHUB_TOKEN=${{ secrets.npmGithubReadToken }} + cache-from: type=registry,ref=${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }} + cache-to: type=inline + context: ${{ github.event.deployment.payload.container.context }} + file: ${{ github.event.deployment.payload.container.file }} + platforms: linux/amd64 + push: true + tags: | + ${{ steps.login-ecr.outputs.registry }}/${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}:latest + ${{ steps.login-ecr.outputs.registry }}/${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}:${{ steps.vars.outputs.version }} + ${{ steps.login-ecr.outputs.registry }}/${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}:${{ github.sha }} + target: ${{ matrix.containerfile_targets }} + consecutive: + needs: [parallel] + environment: ${{ github.event.deployment.payload.env }} + runs-on: ${{ inputs.runner }} + steps: - name: Checkout ${{ inputs.deploymentRepoURL }} git repository uses: actions/checkout@v3 with: @@ -250,19 +314,19 @@ jobs: name: Update ${{ github.event.deployment.payload.name }} version for ${{ github.event.deployment.environment }} values uses: mikefarah/yq@v4.30.8 with: - cmd: yq '(.${{ github.event.deployment.payload.chart }}.image.tag = "${{ steps.vars.outputs.version }}")' -i remote/${{ inputs.deploymentRepoPath }}/${{ github.event.deployment.payload.namespace }}/${{ github.event.deployment.payload.env }}/${{ github.event.deployment.payload.name }}/${{ inputs.versionFilePath }} + cmd: yq '(.${{ github.event.deployment.payload.chart }}.image.tag = "${{ needs.parallel.outputs.version }}")' -i remote/${{ inputs.deploymentRepoPath }}/${{ github.event.deployment.payload.namespace }}/${{ github.event.deployment.payload.env }}/${{ github.event.deployment.payload.name }}/${{ inputs.versionFilePath }} - if: github.event.deployment.payload.schemaVersion == 'v2' name: Update ${{ github.event.deployment.payload.name }} version for ${{ github.event.deployment.environment }} values uses: mikefarah/yq@v4.30.8 with: - cmd: yq '(.${{ github.event.deployment.payload.kubernetes.versionKey }} = "${{ steps.vars.outputs.version }}")' -i remote/${{ inputs.deploymentRepoPath }}/${{ github.event.deployment.payload.kubernetes.namespace }}/${{ github.event.deployment.payload.env }}/${{ github.event.deployment.payload.name }}/${{ inputs.versionFilePath }} + cmd: yq '(.${{ github.event.deployment.payload.kubernetes.versionKey }} = "${{ needs.parallel.outputs.version }}")' -i remote/${{ inputs.deploymentRepoPath }}/${{ github.event.deployment.payload.kubernetes.namespace }}/${{ github.event.deployment.payload.env }}/${{ github.event.deployment.payload.name }}/${{ inputs.versionFilePath }} - name: Commit deployment file run: | cd remote git config --global user.email "${{ inputs.botEmail }}" git config --global user.name "${{ inputs.registryUsername }}" git add . - git commit --allow-empty -m "chore(${{ github.event.deployment.payload.name }}): set ${{ github.event.deployment.payload.env }} version to ${{ steps.vars.outputs.version }}" + git commit --allow-empty -m "chore(${{ github.event.deployment.payload.name }}): set ${{ github.event.deployment.payload.env }} version to ${{ needs.parallel.outputs.version }}" - name: Push changes to ${{ inputs.deploymentRepoURL }} git repository uses: ad-m/github-push-action@0fafdd62b84042d49ec0cb92d9cac7f7ce4ec79e with: @@ -289,14 +353,14 @@ jobs: environment: ${{ github.event.deployment.payload.env }} state: "failure" token: ${{ github.token }} - - if: success() && steps.vars.outputs.channel-id != '' + - if: success() && needs.parallel.outputs.channel-id != '' name: Notify ${{ github.event.deployment.payload.name }} deployment success continue-on-error: true uses: darioblanco/slack-deployment@main env: SLACK_BOT_TOKEN: ${{ secrets.slackBotToken }} with: - channel_id: ${{ steps.vars.outputs.channel-id }} + channel_id: ${{ needs.parallel.outputs.channel-id }} deployment_description: ${{ github.event.deployment.payload.description == null && 'No description' || github.event.deployment.payload.description }} deployment_name: ${{ github.event.deployment.payload.name == null && 'unknown' || github.event.deployment.payload.name }} environment: ${{ github.event.deployment.payload.env == null && 'unknown' || github.event.deployment.payload.env }} @@ -307,7 +371,7 @@ jobs: sha: ${{ github.sha }} status_url: ${{ github.event.deployment.payload.statusUrl == null && 'https://github.com' || github.event.deployment.payload.statusUrl }} url: ${{ github.event.deployment.payload.url == null && 'https://github.com' || github.event.deployment.payload.url }} - version: ${{ steps.vars.outputs.version }} + version: ${{ needs.parallel.outputs.version }} - if: success() && inputs.sentryOrg != '' && inputs.sentryProject != '' name: Create Sentry release uses: getsentry/action-release@v1 @@ -319,7 +383,7 @@ jobs: with: environment: ${{ inputs.sentryEnvironment != '' && inputs.sentryEnvironment || github.event.deployment.payload.env }} set_commits: skip - version: ${{ steps.vars.outputs.version }} + version: ${{ needs.parallel.outputs.version }} continue-on-error: true - name: Clean up images uses: actions/delete-package-versions@v4