From 4ca171ff766164365f19f1986454428edfeb33b3 Mon Sep 17 00:00:00 2001 From: JonJagger Date: Wed, 22 Jan 2025 13:20:11 +0000 Subject: [PATCH] Use workflow action to build and push image --- .github/workflows/main.yml | 123 +++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 65 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1c21783..7d1e201 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -24,14 +24,13 @@ on: env: - CYBER_DOJO_DASHBOARD_BASE_IMAGE: ${{ inputs.BASE_IMAGE }} - KOSLI_CLI_VERSION: ${{ vars.KOSLI_CLI_VERSION }} KOSLI_DRY_RUN: ${{ vars.KOSLI_DRY_RUN }} # false KOSLI_HOST: ${{ vars.KOSLI_HOST }} # https://app.kosli.com KOSLI_API_TOKEN: ${{ secrets.KOSLI_API_TOKEN }} KOSLI_ORG: ${{ vars.KOSLI_ORG }} # cyber-dojo KOSLI_FLOW: ${{ vars.KOSLI_FLOW }} # dashboard-ci KOSLI_TRAIL: ${{ inputs.KOSLI_TRAIL }} + AWS_ACCOUNT_ID: ${{ vars.AWS_ACCOUNT_ID }} AWS_ECR_ID: ${{ vars.AWS_ECR_ID }} AWS_REGION: ${{ vars.AWS_REGION }} @@ -59,7 +58,7 @@ jobs: - name: Prepare outputs for workflow jobs id: vars run: | - IMAGE_TAG=${GITHUB_SHA:0:7} + IMAGE_TAG="${GITHUB_SHA:0:7}" ECR_REGISTRY="${AWS_ECR_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com" IMAGE_NAME="${ECR_REGISTRY}/${SERVICE_NAME}:${IMAGE_TAG}" @@ -75,13 +74,12 @@ jobs: if: ${{ github.ref == 'refs/heads/main' }} uses: kosli-dev/setup-cli-action@v2 with: - version: ${{ env.KOSLI_CLI_VERSION }} + version: ${{ vars.KOSLI_CLI_VERSION }} - name: Begin Kosli Trail if: ${{ github.ref == 'refs/heads/main' }} run: kosli begin trail "${KOSLI_TRAIL}" - --flow="${KOSLI_FLOW}" --template-file=.kosli.yml @@ -101,7 +99,7 @@ jobs: - name: Setup Kosli CLI uses: kosli-dev/setup-cli-action@v2 with: - version: ${{ env.KOSLI_CLI_VERSION }} + version: ${{ vars.KOSLI_CLI_VERSION }} - name: Attest pull-request evidence to Kosli run: @@ -126,7 +124,7 @@ jobs: if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }} uses: kosli-dev/setup-cli-action@v2 with: - version: ${{ env.KOSLI_CLI_VERSION }} + version: ${{ vars.KOSLI_CLI_VERSION }} - name: Attest evidence to Kosli if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }} @@ -163,7 +161,7 @@ jobs: if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }} uses: kosli-dev/setup-cli-action@v2 with: - version: ${{ env.KOSLI_CLI_VERSION }} + version: ${{ vars.KOSLI_CLI_VERSION }} - name: Attest evidence to Kosli if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }} @@ -185,13 +183,13 @@ jobs: - name: Run SonarCloud scan env: SONAR_TOKEN: ${{ secrets.KOSLI_SONAR_API_TOKEN }} - uses: SonarSource/sonarqube-scan-action@v4.2.1 + uses: SonarSource/sonarqube-scan-action@v4 - name: Setup Kosli CLI if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }} uses: kosli-dev/setup-cli-action@v2 with: - version: ${{ env.KOSLI_CLI_VERSION }} + version: ${{ vars.KOSLI_CLI_VERSION }} - name: Attest evidence to Kosli if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }} @@ -210,7 +208,7 @@ jobs: id-token: write contents: write outputs: - artifact_digest: ${{ steps.variables.outputs.artifact_digest }} + digest: ${{ steps.variables.outputs.digest }} steps: - uses: actions/checkout@v4 with: @@ -229,15 +227,26 @@ jobs: id: login-ecr uses: aws-actions/amazon-ecr-login@v2 - - name: Build and push Docker image to ECR + - name: Build and push Docker image to Amazon ECR + id: docker_build + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ${{ env.IMAGE_NAME }} + build-args: | + COMMIT_SHA=${{ github.sha }} + BASE_IMAGE=${{ inputs.BASE_IMAGE }} + + - name: Make image digest available to following jobs + id: variables run: | - make image_server - docker push "${IMAGE_NAME}" + DIGEST=$(echo ${{ steps.docker_build.outputs.digest }} | sed 's/.*://') + echo "digest=${DIGEST}" >> ${GITHUB_OUTPUT} - - name: Tar Docker image - run: | - docker pull ${IMAGE_NAME} - docker image save ${IMAGE_NAME} --output ${IMAGE_TAR_FILENAME} + - name: Save Docker image + run: + docker image save "${IMAGE_NAME}" --output "${IMAGE_TAR_FILENAME}" - name: Cache Docker image uses: actions/cache@v4 @@ -249,14 +258,7 @@ jobs: if: ${{ github.ref == 'refs/heads/main' }} uses: kosli-dev/setup-cli-action@v2 with: - version: ${{ env.KOSLI_CLI_VERSION }} - - - name: Make Digest available to following jobs - if: ${{ github.ref == 'refs/heads/main' }} - id: variables - run: | - FINGERPRINT=$(kosli fingerprint "${IMAGE_NAME}" --artifact-type=docker) - echo "artifact_digest=${FINGERPRINT}" >> ${GITHUB_OUTPUT} + version: ${{ vars.KOSLI_CLI_VERSION }} - name: Attest image provenance to Kosli if: ${{ github.ref == 'refs/heads/main' }} @@ -271,6 +273,7 @@ jobs: needs: [setup, build-image] env: IMAGE_NAME: ${{ needs.setup.outputs.image_name }} + KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.digest }} steps: - uses: actions/checkout@v4 with: @@ -284,7 +287,7 @@ jobs: - name: Load Docker image run: - docker image load --input ${IMAGE_TAR_FILENAME} + docker image load --input "${IMAGE_TAR_FILENAME}" - name: Run unit tests run: @@ -299,12 +302,10 @@ jobs: if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }} uses: kosli-dev/setup-cli-action@v2 with: - version: ${{ env.KOSLI_CLI_VERSION }} + version: ${{ vars.KOSLI_CLI_VERSION }} - name: Attest JUnit test evidence to Kosli if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }} - env: - KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.artifact_digest }} run: kosli attest junit --name=dashboard.unit-test @@ -312,8 +313,6 @@ jobs: - name: Attest coverage evidence to Kosli if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }} - env: - KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.artifact_digest }} run: | KOSLI_COMPLIANT=$([ "${{ steps.coverage.outcome }}" == 'success' ] && echo true || echo false) kosli attest generic \ @@ -327,6 +326,7 @@ jobs: needs: [setup, build-image] env: IMAGE_NAME: ${{ needs.setup.outputs.image_name }} + KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.digest }} SARIF_FILENAME: snyk.container.scan.json steps: - uses: actions/checkout@v4 @@ -341,7 +341,7 @@ jobs: - name: Load Docker image run: - docker image load --input ${IMAGE_TAR_FILENAME} + docker image load --input "${IMAGE_TAR_FILENAME}" - name: Setup Snyk uses: snyk/actions/setup@master @@ -360,12 +360,10 @@ jobs: if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }} uses: kosli-dev/setup-cli-action@v2 with: - version: ${{ env.KOSLI_CLI_VERSION }} + version: ${{ vars.KOSLI_CLI_VERSION }} - name: Attest evidence to Kosli if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }} - env: - KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.artifact_digest }} run: kosli attest snyk --attachments=.snyk @@ -379,15 +377,14 @@ jobs: needs: [setup, build-image, rubocop-lint, pull-request, unit-tests, snyk-container-scan, snyk-code-scan, sonarcloud-scan] env: IMAGE_NAME: ${{ needs.setup.outputs.image_name }} + KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.digest }} steps: - name: Setup Kosli CLI uses: kosli-dev/setup-cli-action@v2 with: - version: ${{ env.KOSLI_CLI_VERSION }} + version: ${{ vars.KOSLI_CLI_VERSION }} - name: Kosli SDLC gate to short-circuit the workflow - env: - KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.artifact_digest }} run: kosli assert artifact "${IMAGE_NAME}" @@ -397,6 +394,7 @@ jobs: needs: [setup, build-image, sdlc-control-gate] env: IMAGE_NAME: ${{ needs.setup.outputs.image_name }} + KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.digest }} environment: name: staging url: https://beta.cyber-dojo.org @@ -408,11 +406,10 @@ jobs: - name: Setup Kosli CLI uses: kosli-dev/setup-cli-action@v2 with: - version: ${{ env.KOSLI_CLI_VERSION }} + version: ${{ vars.KOSLI_CLI_VERSION }} - name: Report approval of deployment to Kosli env: - KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.artifact_digest }} KOSLI_ENVIRONMENT: aws-beta run: kosli report approval "${IMAGE_NAME}" @@ -430,6 +427,7 @@ jobs: needs: [setup, build-image, deploy-to-beta] env: IMAGE_NAME: ${{ needs.setup.outputs.image_name }} + KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.digest }} environment: name: production url: https://cyber-dojo.org @@ -441,11 +439,10 @@ jobs: - name: Setup Kosli CLI uses: kosli-dev/setup-cli-action@v2 with: - version: ${{ env.KOSLI_CLI_VERSION }} + version: ${{ vars.KOSLI_CLI_VERSION }} - name: Report approval of deployment to Kosli env: - KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.artifact_digest }} KOSLI_ENVIRONMENT: aws-prod run: kosli report approval "${IMAGE_NAME}" @@ -469,35 +466,31 @@ jobs: push-latest: runs-on: ubuntu-latest needs: [setup, deploy-to-prod] - permissions: - id-token: write - contents: write + env: + IMAGE_NAME: ${{ needs.setup.outputs.image_name }} + IMAGE_TAG: ${{ needs.setup.outputs.image_tag }} steps: - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4 + - name: Retrieve Docker image from cache + uses: actions/cache@v4 with: - aws-region: ${{ needs.setup.outputs.aws_region }} - role-duration-seconds: 900 - role-session-name: ${{ github.event.repository.name }} - role-to-assume: arn:aws:iam::${{ needs.setup.outputs.aws_account_id }}:role/${{ needs.setup.outputs.gh_actions_iam_role_name }} - mask-aws-account-id: no + path: ${{ env.IMAGE_TAR_FILENAME }} + key: ${{ env.IMAGE_NAME }} - - name: Login to Amazon ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@v2 + - name: Load Docker image + run: + docker image load --input "${IMAGE_TAR_FILENAME}" - uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USER }} password: ${{ secrets.DOCKER_PASS }} - - name: Tag image to :latest and push to Dockerhub Registry - env: - IMAGE_NAME: ${{ needs.setup.outputs.image_name }} - IMAGE_TAG: ${{ needs.setup.outputs.image_tag }} + - name: Tag images and push to Dockerhub run: | - docker pull "${IMAGE_NAME}" - docker tag "${IMAGE_NAME}" cyberdojo/${SERVICE_NAME}:${IMAGE_TAG} - docker tag "${IMAGE_NAME}" cyberdojo/${SERVICE_NAME}:latest - docker push cyberdojo/${SERVICE_NAME}:${IMAGE_TAG} - docker push cyberdojo/${SERVICE_NAME}:latest + TAGGED="cyberdojo/${SERVICE_NAME}:${IMAGE_TAG}" + docker tag "${IMAGE_NAME}" "${TAGGED}" + docker push "${TAGGED}" + + LATEST="cyberdojo/${SERVICE_NAME}:latest" + docker tag "${IMAGE_NAME}" "${LATEST}" + docker push "${LATEST}"