chore: align ECR retention policies #1
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Reusable Container | ||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| appName: | ||
| required: true | ||
| description: The container image name | ||
| type: string | ||
| baseImageRegistry: | ||
| required: false | ||
| description: The registry to pull base images from | ||
| type: string | ||
| contextPath: | ||
| required: false | ||
| description: The container context to build the image | ||
| default: . | ||
| type: string | ||
| enableContainerScan: | ||
| required: false | ||
| description: Apply the container scan | ||
| default: true | ||
| type: boolean | ||
| extraBuildArgs: | ||
| required: false | ||
| description: Extra build arguments for building the docker image (KEY=VALUE separated by new lines) | ||
| default: "" | ||
| type: string | ||
| filePath: | ||
| required: false | ||
| description: The file path for the Container image | ||
| default: Containerfile | ||
| type: string | ||
| imageScanSeverity: | ||
| required: false | ||
| description: The base severity for the image scan | ||
| default: LOW | ||
| type: string | ||
| imageScanSeverityThreshold: | ||
| required: false | ||
| description: The severity threshold to fail the pipeline on findings | ||
| default: CRITICAL | ||
| type: string | ||
| imageScanTimeout: | ||
| required: false | ||
| description: Timeout for the trivy scan | ||
| default: 10m | ||
| type: string | ||
| imageScanAnnotations: | ||
| required: false | ||
| description: Boolean flag to scan annotations | ||
| default: true | ||
| type: boolean | ||
| runner: | ||
| required: false | ||
| description: Runner type | ||
| default: ubuntu-latest | ||
| type: string | ||
| version: | ||
| required: true | ||
| description: The version to push | ||
| type: string | ||
| secrets: | ||
| npmGithubReadToken: | ||
| required: false | ||
| description: The Github token with permissions to read NPM private packages | ||
| AWS_ROLE_TO_ASSUME: | ||
| required: true | ||
| description: AWS OIDC role for GitHub to assume | ||
| baseImageRegistryUsername: | ||
| required: false | ||
| description: The username for the base image registry | ||
| baseImageRegistryPassword: | ||
| required: false | ||
| description: The password for the base image registry | ||
| jobs: | ||
| build-ecr-single: | ||
| permissions: | ||
| id-token: write | ||
| contents: read | ||
| runs-on: ${{ inputs.runner }} | ||
| steps: | ||
| - name: Checkout current git repository | ||
| uses: actions/checkout@v4 | ||
| - name: Validate base image registry secrets | ||
| if: ${{ inputs.baseImageRegistry }} | ||
| run: | | ||
| if [ -z "${{ secrets.baseImageRegistryUsername }}" ] || [ -z "${{ secrets.baseImageRegistryPassword }}" ]; then | ||
| echo "baseImageRegistry is set but baseImageRegistryUsername or baseImageRegistryPassword secrets are missing." | ||
| exit 1 | ||
| fi | ||
| - name: Login to base image registry | ||
| if: ${{ inputs.baseImageRegistry }} | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| registry: ${{ inputs.baseImageRegistry }} | ||
| username: ${{ secrets.baseImageRegistryUsername }} | ||
| password: ${{ secrets.baseImageRegistryPassword }} | ||
| - name: Set up Docker Buildx | ||
| uses: docker/setup-buildx-action@v2 | ||
| - name: Configure AWS credentials | ||
| uses: aws-actions/configure-aws-credentials@v3 | ||
| with: | ||
| aws-region: eu-central-1 | ||
| role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} | ||
| - name: Create ECR repository if it doesn't exist | ||
| run: | | ||
| aws ecr describe-repositories --repository-names ${{ inputs.appName }} || \ | ||
| aws ecr create-repository --repository-name ${{ inputs.appName }} | ||
| echo "Applying lifecycle policies" | ||
| LIFECYCLE_POLICY='{"rules":[ | ||
| {"rulePriority":1,"description":"Preserve preview images","selection":{"tagStatus":"tagged","tagPatternList":["preview-*"],"countType":"sinceImagePushed","countUnit":"days","countNumber":365},"action":{"type":"expire"}}, | ||
| {"rulePriority":2,"description":"Preserve production images","selection":{"tagStatus":"tagged","tagPatternList":["v*"],"countType":"imageCountMoreThan","countNumber":50},"action":{"type":"expire"}}, | ||
| {"rulePriority":3,"description":"Remove untagged images","selection":{"tagStatus":"untagged","countType":"sinceImagePushed","countUnit":"days","countNumber":7},"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 | ||
| id: login-ecr | ||
| uses: aws-actions/amazon-ecr-login@v2 | ||
| - name: Build image | ||
| uses: docker/build-push-action@v6 | ||
| with: | ||
| build-args: | | ||
| GITHUB_SHA=${{ github.sha }} | ||
| VERSION=${{ inputs.version }} | ||
| NPM_GITHUB_TOKEN=${{ secrets.npmGithubReadToken }} | ||
| ${{ inputs.extraBuildArgs }} | ||
| cache-from: type=registry,ref=${{ steps.login-ecr.outputs.registry }}/${{ inputs.appName }}:cache | ||
| cache-to: mode=max,image-manifest=true,oci-mediatypes=true,type=registry,ref=${{ steps.login-ecr.outputs.registry }}/${{ inputs.appName }}:cache | ||
| context: ${{ inputs.contextPath }} | ||
| load: true | ||
| file: ${{ inputs.filePath }} | ||
| platforms: linux/amd64 | ||
| tags: | | ||
| ${{ steps.login-ecr.outputs.registry }}/${{ inputs.appName }}:latest | ||
| ${{ steps.login-ecr.outputs.registry }}/${{ inputs.appName }}:${{ inputs.version }} | ||
| ${{ steps.login-ecr.outputs.registry }}/${{ inputs.appName }}:${{ github.sha }} | ||
| - name: Scan for vulnerabilities | ||
| if: inputs.enableContainerScan | ||
| uses: crazy-max/ghaction-container-scan@v3 | ||
| with: | ||
| image: ${{ steps.login-ecr.outputs.registry }}/${{ inputs.appName }}:latest | ||
| dockerfile: Containerfile | ||
| severity: ${{ inputs.imageScanSeverity }} | ||
| severity_threshold: ${{ inputs.imageScanSeverityThreshold }} | ||
| annotations: ${{ inputs.imageScanAnnotations }} | ||
| env: | ||
| TRIVY_TIMEOUT: ${{ inputs.imageScanTimeout }} | ||
| - name: Push image to ECR | ||
| run: | | ||
| docker push -a ${{ steps.login-ecr.outputs.registry }}/${{ inputs.appName }} | ||