From c75da7f1e01548a79470686982f31dd21db2ec13 Mon Sep 17 00:00:00 2001 From: JonJagger Date: Sat, 2 Mar 2024 12:04:45 +0000 Subject: [PATCH] Switch to canonical ci yaml workflows --- .github/workflows/main.yml | 312 +++++++++++--- .github/workflows/main_staging.yml | 313 ++++++++++++++ .github/workflows/sub_deploy_to_beta.yml | 194 +++++++++ .github/workflows/sub_deploy_to_prod.yml | 193 +++++++++ .kosli.yml | 4 +- Makefile | 22 + README.md | 5 +- build_test.sh | 4 + docs/snapshot.json | 401 ++++++++++++++++++ sh/build_test_tag.sh | 64 +++ .../dead/build_test_publish.sh | 7 +- sh/{ => dead}/kosli.sh | 12 - sh/dead/main.yml | 71 ++++ sh/echo_versioner_env_vars.sh | 36 +- sh/lib.sh | 25 ++ sh/update_image_lists.sh | 3 +- sh/wait_for_deployment.sh | 71 ++++ sh/wait_for_image.sh | 20 + 18 files changed, 1647 insertions(+), 110 deletions(-) create mode 100644 .github/workflows/main_staging.yml create mode 100644 .github/workflows/sub_deploy_to_beta.yml create mode 100644 .github/workflows/sub_deploy_to_prod.yml create mode 100644 Makefile create mode 100755 build_test.sh create mode 100644 docs/snapshot.json create mode 100755 sh/build_test_tag.sh rename build_test_publish.sh => sh/dead/build_test_publish.sh (95%) rename sh/{ => dead}/kosli.sh (95%) create mode 100644 sh/dead/main.yml create mode 100755 sh/lib.sh create mode 100755 sh/wait_for_deployment.sh create mode 100755 sh/wait_for_image.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9213431..b259d93 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,71 +1,275 @@ -name: Main +name: Main - reports Trails to https://app.kosli.com on: push: branches: - main +env: + KOSLI_DRY_RUN: ${{ vars.KOSLI_DRY_RUN }} # False + KOSLI_HOST: ${{ vars.KOSLI_HOST }} # https://app.kosli.com + KOSLI_HOST_STAGING: ${{ vars.KOSLI_HOST_STAGING }} # https://staging.app.kosli.com + KOSLI_ORG: ${{ vars.KOSLI_ORG }} # cyber-dojo + KOSLI_FLOW: languages-start-points-ci + KOSLI_API_TOKEN: ${{ secrets.KOSLI_API_TOKEN }} + KOSLI_TRAIL: ${{ github.sha }} + jobs: - pre-build: + + kosli-trail: runs-on: ubuntu-latest outputs: - image_tag: ${{ steps.prep.outputs.image_tag }} + image_tag: ${{ steps.variables.outputs.image_tag }} + image_name: ${{ steps.variables.outputs.image_name }} steps: - - uses: actions/checkout@v3 - - name: Prepare - id: prep - run: | - TAG=$(echo $GITHUB_SHA | head -c7) - echo "image_tag=${TAG}" >> ${GITHUB_OUTPUT} - - build-test-push: - needs: [pre-build] - uses: cyber-dojo/reusable-actions-workflows/.github/workflows/kosli_build_test_push.yml@v0.0.11 - secrets: - KOSLI_API_TOKEN: ${{ secrets.KOSLI_API_TOKEN }} - KOSLI_API_TOKEN_STAGING: ${{ secrets.KOSLI_API_TOKEN_STAGING }} - DOCKER_PASS: ${{ secrets.DOCKER_PASS }} - DOCKER_USER: ${{ secrets.DOCKER_USER }} - SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + - uses: actions/checkout@v4 + + - name: Setup Kosli CLI + uses: kosli-dev/setup-cli-action@v2 + with: + version: ${{ vars.KOSLI_CLI_VERSION }} + + - name: Create Kosli Flow + run: + kosli create flow "${{ env.KOSLI_FLOW }}" + --description="Language+TestFramework choices" + --template-file=.kosli.yml + + - name: Begin Kosli Trail + run: + kosli begin trail "${{ env.KOSLI_TRAIL }}" + + - name: Set outputs + id: variables + run: | + IMAGE_TAG=${GITHUB_SHA:0:7} + echo "image_tag=${IMAGE_TAG}" >> ${GITHUB_OUTPUT} + echo "image_name=cyberdojo/languages-start-points:${IMAGE_TAG}" >> ${GITHUB_OUTPUT} + + +# pull-request: +# needs: [kosli-trail] +# runs-on: ubuntu-latest +# permissions: +# id-token: write +# contents: write +# pull-requests: read +# steps: +# - uses: actions/checkout@v4 +# +# - name: Setup Kosli CLI +# uses: kosli-dev/setup-cli-action@v2 +# with: +# version: ${{ vars.KOSLI_CLI_VERSION }} +# +# - name: Attest pull-request evidence to Kosli Trail +# run: +# kosli attest pullrequest github +# --github-token=${{ secrets.GITHUB_TOKEN }} +# --name=languages-start-points.pull-request + + + build-image: + needs: [kosli-trail] + runs-on: ubuntu-latest + env: + IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} + outputs: + kosli_fingerprint: ${{ steps.variables.outputs.kosli_fingerprint }} + steps: + - uses: actions/checkout@v4 + + - name: Build image + run: + make build + + - uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USER }} + password: ${{ secrets.DOCKER_PASS }} + + - name: Push image to Dockerhub registry + run: + docker push "${IMAGE_NAME}" + + - name: Setup Kosli CLI + uses: kosli-dev/setup-cli-action@v2 + with: + version: ${{ vars.KOSLI_CLI_VERSION }} + + - name: Attest image evidence to Kosli Trail + run: + kosli attest artifact "${IMAGE_NAME}" + --artifact-type=docker + --name=languages-start-points + --trail="${GITHUB_SHA}" + + - name: Set outputs + id: variables + run: | + FINGERPRINT=$(kosli fingerprint "${IMAGE_NAME}" --artifact-type=docker) + echo "kosli_fingerprint=${FINGERPRINT}" >> ${GITHUB_OUTPUT} + + + snyk-container-scan: + needs: [build-image, kosli-trail] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Kosli CLI + uses: kosli-dev/setup-cli-action@v2 + with: + version: ${{ vars.KOSLI_CLI_VERSION }} + + - name: Setup Snyk + uses: snyk/actions/setup@master + + - name: Run Snyk container scan and report results to Kosli Trail + env: + IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} + KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.kosli_fingerprint }} + KOSLI_ATTACHMENTS: /tmp/kosli_attachments + SARIF_FILENAME: snyk.container.scan.json + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + run: | + set +e + snyk container test ${IMAGE_NAME} \ + --sarif \ + --sarif-file-output="${SARIF_FILENAME}" \ + --policy-path=.snyk + set -e + + mkdir "${KOSLI_ATTACHMENTS}" + cp .snyk "${KOSLI_ATTACHMENTS}" + + kosli attest snyk "${IMAGE_NAME}" \ + --name=languages-start-points.snyk-container-scan \ + --scan-results="${SARIF_FILENAME}" + + + snyk-code-scan: + needs: [build-image, kosli-trail] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Kosli CLI + uses: kosli-dev/setup-cli-action@v2 + with: + version: ${{ vars.KOSLI_CLI_VERSION }} + + - name: Setup Snyk + uses: snyk/actions/setup@master + + - name: Run Snyk code scan and report results to Kosli Trail + env: + IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} + KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.kosli_fingerprint }} + KOSLI_ATTACHMENTS: /tmp/kosli_attachments + SARIF_FILENAME: snyk.code.scan.json + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + run: | + set +e + snyk code test \ + --sarif \ + --sarif-file-output="${SARIF_FILENAME}" \ + --policy-path=.snyk \ + . + set -e + + mkdir "${KOSLI_ATTACHMENTS}" + cp .snyk "${KOSLI_ATTACHMENTS}" + + kosli attest snyk "${IMAGE_NAME}" \ + --name=languages-start-points.snyk-code-scan \ + --scan-results="${SARIF_FILENAME}" + + + sdlc-control-gate: + needs: [snyk-container-scan, snyk-code-scan, kosli-trail, build-image] + runs-on: ubuntu-latest + steps: + - name: Setup Kosli CLI + uses: kosli-dev/setup-cli-action@v2 + with: + version: ${{ vars.KOSLI_CLI_VERSION }} + + - name: Kosli SDLC gate to short-circuit the Trail + env: + IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} + KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.kosli_fingerprint }} + run: + kosli assert artifact ${IMAGE_NAME} + + + approve-deployment-to-beta: + needs: [sdlc-control-gate, kosli-trail, build-image] + runs-on: ubuntu-latest + environment: + name: staging + url: ${{ vars.KOSLI_HOST_STAGING }} + env: + IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} + KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.kosli_fingerprint }} + KOSLI_ENVIRONMENT: aws-beta + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Kosli CLI + uses: kosli-dev/setup-cli-action@v2 + with: + version: ${{ vars.KOSLI_CLI_VERSION }} + + - name: Attest approval of deployment to Kosli + run: + kosli report approval ${IMAGE_NAME} + --approver="${{ github.actor }}" + + + deploy-to-beta: + needs: [approve-deployment-to-beta, kosli-trail] + uses: ./.github/workflows/sub_deploy_to_beta.yml with: - BUILD_COMMAND: build_test_publish.sh - image_tag: ${{ needs.pre-build.outputs.image_tag }} - AWS_ACCOUNT_ID: 244531986313 - AWS_REGION: eu-central-1 - ecr_registry: 244531986313.dkr.ecr.eu-central-1.amazonaws.com - service_name: languages-start-points - gh_actions_iam_role_name: gh_actions_services - - deploy-staging: - needs: [pre-build, build-test-push] - uses: cyber-dojo/reusable-actions-workflows/.github/workflows/kosli_deploy.yml@v0.0.11 + IMAGE_TAG: ${{ needs.kosli-trail.outputs.image_tag }} secrets: KOSLI_API_TOKEN: ${{ secrets.KOSLI_API_TOKEN }} KOSLI_API_TOKEN_STAGING: ${{ secrets.KOSLI_API_TOKEN_STAGING }} + + + approve-deployment-to-prod: + needs: [deploy-to-beta, kosli-trail, build-image] + runs-on: ubuntu-latest + environment: + name: production + url: ${{ vars.KOSLI_HOST }} + env: + IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} + KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.kosli_fingerprint }} + KOSLI_ENVIRONMENT: aws-prod + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Kosli CLI + uses: kosli-dev/setup-cli-action@v2 + with: + version: ${{ vars.KOSLI_CLI_VERSION }} + + - name: Attest approval of deployment to Kosli + run: + kosli report approval ${IMAGE_NAME} + --approver="${{ github.actor }}" + + + deploy-to-prod: + needs: [approve-deployment-to-prod, kosli-trail] + uses: ./.github/workflows/sub_deploy_to_prod.yml with: - tagged_image: 244531986313.dkr.ecr.eu-central-1.amazonaws.com/languages-start-points:${{ needs.pre-build.outputs.image_tag }} - AWS_ACCOUNT_ID: 244531986313 - AWS_REGION: eu-central-1 - gh_actions_iam_role_name: gh_actions_services - environment_url: https://beta.cyber-dojo.org - environment_name: staging - cyber_dojo_env_name_aws: aws-beta - kosli_host_staging: https://staging.app.kosli.com - kosli_host_production: https://app.kosli.com - - deploy-prod: - needs: [pre-build, build-test-push, deploy-staging] - uses: cyber-dojo/reusable-actions-workflows/.github/workflows/kosli_deploy.yml@v0.0.11 + IMAGE_TAG: ${{ needs.kosli-trail.outputs.image_tag }} secrets: KOSLI_API_TOKEN: ${{ secrets.KOSLI_API_TOKEN }} - KOSLI_API_TOKEN_STAGING: ${{ secrets.KOSLI_API_TOKEN_STAGING }} - with: - tagged_image: 274425519734.dkr.ecr.eu-central-1.amazonaws.com/languages-start-points:${{ needs.pre-build.outputs.image_tag }} - AWS_ACCOUNT_ID: 274425519734 - AWS_REGION: eu-central-1 - gh_actions_iam_role_name: gh_actions_services - environment_url: https://cyber-dojo.org - environment_name: production - cyber_dojo_env_name_aws: aws-prod - kosli_host_staging: https://staging.app.kosli.com - kosli_host_production: https://app.kosli.com + KOSLI_API_TOKEN_STAGING: ${{ secrets.KOSLI_API_TOKEN_STAGING }} \ No newline at end of file diff --git a/.github/workflows/main_staging.yml b/.github/workflows/main_staging.yml new file mode 100644 index 0000000..5a93b4c --- /dev/null +++ b/.github/workflows/main_staging.yml @@ -0,0 +1,313 @@ +name: Main - reports Trails to https://staging.app.kosli.com + +on: + push: + branches: + - main + +env: + KOSLI_DRY_RUN: ${{ vars.KOSLI_DRY_RUN }} # False + KOSLI_HOST: ${{ vars.KOSLI_HOST_STAGING }} # https://staging.app.kosli.com + KOSLI_ORG: ${{ vars.KOSLI_ORG }} # cyber-dojo + KOSLI_FLOW: languages-start-points-ci + KOSLI_API_TOKEN: ${{ secrets.KOSLI_API_TOKEN_STAGING }} + KOSLI_TRAIL: ${{ github.sha }} + +jobs: + + kosli-trail: + runs-on: ubuntu-latest + outputs: + image_tag: ${{ steps.variables.outputs.image_tag }} + image_name: ${{ steps.variables.outputs.image_name }} + steps: + - uses: actions/checkout@v4 + + - name: Setup Kosli CLI + uses: kosli-dev/setup-cli-action@v2 + with: + version: ${{ vars.KOSLI_CLI_VERSION }} + + - name: Create Kosli Flow + run: + kosli create flow "${{ env.KOSLI_FLOW }}" + --description="Language+TestFramework choices" + --template-file=.kosli.yml + + - name: Begin Kosli Trail + run: + kosli begin trail "${{ env.KOSLI_TRAIL }}" + + - name: Set outputs + id: variables + run: | + IMAGE_TAG=${GITHUB_SHA:0:7} + echo "image_tag=${IMAGE_TAG}" >> ${GITHUB_OUTPUT} + echo "image_name=cyberdojo/languages-start-points:${IMAGE_TAG}" >> ${GITHUB_OUTPUT} + + +# pull-request: +# needs: [kosli-trail] +# runs-on: ubuntu-latest +# permissions: +# id-token: write +# contents: write +# pull-requests: read +# steps: +# - uses: actions/checkout@v4 +# +# - name: Setup Kosli CLI +# uses: kosli-dev/setup-cli-action@v2 +# with: +# version: ${{ vars.KOSLI_CLI_VERSION }} +# +# - name: Report pull-request evidence to Kosli Trail +# run: +# kosli attest pullrequest github +# --github-token=${{ secrets.GITHUB_TOKEN }} +# --name=languages-start-points.pull-request + + + wait-for-image: + needs: [kosli-trail] + runs-on: ubuntu-latest + env: + IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} + outputs: + kosli_fingerprint: ${{ steps.variables.outputs.kosli_fingerprint }} + steps: + - uses: actions/checkout@v4 + + - name: Wait for image to be built in main.yml + run: + ./sh/wait_for_image.sh "${IMAGE_NAME}" + + - name: Setup Kosli CLI + uses: kosli-dev/setup-cli-action@v2 + with: + version: ${{ vars.KOSLI_CLI_VERSION }} + + - name: Attest image to Kosli Trail + run: + kosli attest artifact "${IMAGE_NAME}" + --artifact-type=docker + --name=languages-start-points + + - name: Set outputs + id: variables + run: | + FINGERPRINT=$(kosli fingerprint "${IMAGE_NAME}" --artifact-type=docker) + echo "kosli_fingerprint=${FINGERPRINT}" >> ${GITHUB_OUTPUT} + + + snyk-container-scan: + needs: [wait-for-image, kosli-trail] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Kosli CLI + uses: kosli-dev/setup-cli-action@v2 + with: + version: ${{ vars.KOSLI_CLI_VERSION }} + + - name: Setup Snyk + uses: snyk/actions/setup@master + + - name: Run Snyk container scan and report results to Kosli Trail + env: + IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} + KOSLI_FINGERPRINT: ${{ needs.wait-for-image.outputs.kosli_fingerprint }} + KOSLI_ATTACHMENTS: /tmp/kosli_attachments + SARIF_FILENAME: snyk.container.scan.json + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + run: | + set +e + snyk container test ${IMAGE_NAME} \ + --sarif \ + --sarif-file-output="${SARIF_FILENAME}" \ + --policy-path=.snyk + set -e + + mkdir "${KOSLI_ATTACHMENTS}" + cp .snyk "${KOSLI_ATTACHMENTS}" + + kosli attest snyk "${IMAGE_NAME}" \ + --name=languages-start-points.snyk-container-scan \ + --scan-results="${SARIF_FILENAME}" + + + snyk-code-scan: + needs: [wait-for-image, kosli-trail] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Kosli CLI + uses: kosli-dev/setup-cli-action@v2 + with: + version: ${{ vars.KOSLI_CLI_VERSION }} + + - name: Setup Snyk + uses: snyk/actions/setup@master + + - name: Run Snyk code scan and report results to Kosli Trail + env: + IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} + KOSLI_FINGERPRINT: ${{ needs.wait-for-image.outputs.kosli_fingerprint }} + KOSLI_ATTACHMENTS: /tmp/kosli_attachments + SARIF_FILENAME: snyk.code.scan.json + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + run: | + set +e + snyk code test \ + --sarif \ + --sarif-file-output="${SARIF_FILENAME}" \ + --policy-path=.snyk \ + . + set -e + + mkdir "${KOSLI_ATTACHMENTS}" + cp .snyk "${KOSLI_ATTACHMENTS}" + + kosli attest snyk "${IMAGE_NAME}" \ + --name=languages-start-points.snyk-code-scan \ + --scan-results="${SARIF_FILENAME}" + + + sdlc-control-gate: + needs: [snyk-container-scan, snyk-code-scan, kosli-trail, wait-for-image] + runs-on: ubuntu-latest + steps: + - name: Setup Kosli CLI + uses: kosli-dev/setup-cli-action@v2 + with: + version: ${{ vars.KOSLI_CLI_VERSION }} + + - name: Kosli SDLC gate to short-circuit the Trail + env: + IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} + KOSLI_FINGERPRINT: ${{ needs.wait-for-image.outputs.kosli_fingerprint }} + run: + kosli assert artifact ${IMAGE_NAME} + + + approve-deployment-to-beta: + needs: [sdlc-control-gate, kosli-trail, wait-for-image] + runs-on: ubuntu-latest + env: + IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} + KOSLI_FINGERPRINT: ${{ needs.wait-for-image.outputs.kosli_fingerprint }} + KOSLI_ENVIRONMENT: aws-beta + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Kosli CLI + uses: kosli-dev/setup-cli-action@v2 + with: + version: ${{ vars.KOSLI_CLI_VERSION }} + + - name: Report approval of deployment to Kosli + run: + kosli report approval ${IMAGE_NAME} + --approver="${{ github.actor }}" + + + wait-for-deploy-to-beta: + needs: [approve-deployment-to-beta, kosli-trail] + runs-on: ubuntu-latest + env: + IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} + KOSLI_ENVIRONMENT: aws-beta + steps: + - name: Setup Kosli CLI + uses: kosli-dev/setup-cli-action@v2 + with: + version: ${{ vars.KOSLI_CLI_VERSION }} + + - uses: actions/checkout@v4 + + - name: Wait for deployment to aws-beta in main.yml + run: + ./sh/wait_for_deployment.sh + "${IMAGE_NAME}" + "${{ env.KOSLI_HOST }}" + "${{ env.KOSLI_API_TOKEN }}" + "${{ env.KOSLI_ORG }}" + "${KOSLI_ENVIRONMENT}" + + + approve-deployment-to-prod: + needs: [wait-for-deploy-to-beta, kosli-trail, wait-for-image] + runs-on: ubuntu-latest + env: + IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} + KOSLI_FINGERPRINT: ${{ needs.wait-for-image.outputs.kosli_fingerprint }} + KOSLI_ENVIRONMENT: aws-prod + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Kosli CLI + uses: kosli-dev/setup-cli-action@v2 + with: + version: ${{ vars.KOSLI_CLI_VERSION }} + + - name: Report approval of deployment to Kosli + run: + kosli report approval ${IMAGE_NAME} + --approver="${{ github.actor }}" + + + wait-for-deploy-to-prod: + needs: [approve-deployment-to-prod, kosli-trail] + runs-on: ubuntu-latest + env: + IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} + KOSLI_ENVIRONMENT: aws-prod + steps: + - name: Setup Kosli CLI + uses: kosli-dev/setup-cli-action@v2 + with: + version: ${{ vars.KOSLI_CLI_VERSION }} + + - uses: actions/checkout@v4 + + - name: Wait for deployment to aws-prod in main.yml + run: + ./sh/wait_for_deployment.sh + "${IMAGE_NAME}" + "${{ env.KOSLI_HOST }}" + "${{ env.KOSLI_API_TOKEN }}" + "${{ env.KOSLI_ORG }}" + "${KOSLI_ENVIRONMENT}" + + + # The cyberdojo/versioner refresh-env.sh script + # https://github.com/cyber-dojo/versioner/blob/master/sh/refresh-env.sh + # relies on being able to: + # - get the :latest image + # - extract the SHA env-var embedded inside it + # - use the 1st 7 chars of the SHA as a latest-equivalent tag + + push-latest: + needs: [wait-for-deploy-to-prod, kosli-trail] + runs-on: ubuntu-latest + env: + IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} + steps: + - uses: actions/checkout@v4 + + - uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USER }} + password: ${{ secrets.DOCKER_PASS }} + + - name: Tag image to :latest and push to Dockerhub Registry + run: | + docker pull "${IMAGE_NAME}" + docker tag "${IMAGE_NAME}" cyberdojo/languages-start-points:latest + docker push cyberdojo/languages-start-points:latest diff --git a/.github/workflows/sub_deploy_to_beta.yml b/.github/workflows/sub_deploy_to_beta.yml new file mode 100644 index 0000000..e4df1af --- /dev/null +++ b/.github/workflows/sub_deploy_to_beta.yml @@ -0,0 +1,194 @@ +name: Sub - deploy to aws-beta + +on: + workflow_call: + inputs: + IMAGE_TAG: + required: true + type: string + secrets: + KOSLI_API_TOKEN_STAGING: + required: true + KOSLI_API_TOKEN: + required: true + + +env: + KOSLI_ORG: cyber-dojo + KOSLI_FLOW: languages-start-points-ci + KOSLI_TRAIL: ${{ github.sha }} + KOSLI_HOST: "https://app.kosli.com" + KOSLI_HOST_STAGING: "https://staging.app.kosli.com" + + +jobs: + + variables: + runs-on: ubuntu-latest + outputs: + service_name: ${{ steps.vars.outputs.service_name }} + image_tag: ${{ steps.vars.outputs.image_tag }} + aws_account_id: ${{ steps.vars.outputs.aws_account_id }} + ecr_registry: ${{ steps.vars.outputs.ecr_registry }} + aws_region: ${{ steps.vars.outputs.aws_region }} + gh_actions_iam_role_name: ${{ steps.vars.outputs.gh_actions_iam_role_name }} + steps: + - name: Prepare outputs for fivexl deployment workflow + id: vars + run: | + echo "service_name=languages-start-points" >> ${GITHUB_OUTPUT} + echo "image_tag=${{ inputs.IMAGE_TAG }}" >> ${GITHUB_OUTPUT} + echo "aws_account_id=244531986313" >> ${GITHUB_OUTPUT} + echo "ecr_registry=244531986313.dkr.ecr.eu-central-1.amazonaws.com" >> ${GITHUB_OUTPUT} + echo "aws_region=eu-central-1" >> ${GITHUB_OUTPUT} + echo "gh_actions_iam_role_name=gh_actions_services" >> ${GITHUB_OUTPUT} + + push-image-to-beta-ecr: + needs: [variables] + runs-on: ubuntu-latest + permissions: + id-token: write + contents: write + steps: + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ needs.variables.outputs.aws_region }} + role-duration-seconds: 2400 + role-session-name: ${{ github.event.repository.name }} + role-to-assume: arn:aws:iam::${{ needs.variables.outputs.aws_account_id }}:role/${{ needs.variables.outputs.gh_actions_iam_role_name }} + + - name: Login to Amazon ECR (Elastic Container Registry) + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + + - name: Push image to private beta-ECR + run: | + PUBLIC_IMAGE_NAME=cyberdojo/${{ needs.variables.outputs.service_name }}:${{ inputs.IMAGE_TAG }} + PRIVATE_IMAGE_NAME=${{ needs.variables.outputs.ecr_registry }}/${{ needs.variables.outputs.service_name }}:${{ inputs.IMAGE_TAG }} + docker pull ${PUBLIC_IMAGE_NAME} + docker tag ${PUBLIC_IMAGE_NAME} ${PRIVATE_IMAGE_NAME} + docker push ${PRIVATE_IMAGE_NAME} + + deploy-to-aws-beta: + needs: [variables, push-image-to-beta-ecr] + permissions: + id-token: write + contents: write + uses: fivexl/gh-workflow-tf-plan-apply/.github/workflows/base.yml@v0.0.18 + with: + aws_region: ${{ needs.variables.outputs.aws_region }} + aws_role_arn: arn:aws:iam::${{ needs.variables.outputs.aws_account_id }}:role/${{ needs.variables.outputs.gh_actions_iam_role_name }} + aws_default_region: ${{ needs.variables.outputs.aws_region }} + aws_role_duration: 900 + working_directory: deployment/terraform/ + tf_apply: 'true' + tf_version: v1.4.5 + tf_additional_env_vars: '{"TF_VAR_TAGGED_IMAGE": "${{ needs.variables.outputs.ecr_registry }}/${{ needs.variables.outputs.service_name }}:${{ needs.variables.outputs.image_tag }}"}' +# tf_sh_version: 0.2.1 +# tf_upload_artifact_name_suffix: "_beta" +# tf_upload_artifact_state_file: 'true' +# tf_upload_artifact_plan: 'true' +# tf_state_file_dir_on_s3: "terraform/${{ needs.variables.outputs.service_name }}" +# tf_state_file_name: "${{ needs.variables.outputs.service_name }}.tfstate" + + trail-attest-terraform: + needs: deploy-to-aws-beta + if: false # WIP + permissions: + actions: write + contents: read + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup kosli cli + uses: kosli-dev/setup-cli-action@v2 + with: + version: + ${{ vars.KOSLI_CLI_VERSION }} + + - name: Download a plan artifact + uses: actions/download-artifact@v4.1.1 + with: + name: tf_artifacts_plan_beta + + - name: Download a state file artifact + uses: actions/download-artifact@v4.1.1 + with: + name: tf_artifacts_state_file_beta + + - name: Attest tf plan to Kosli trail (production) + run: + kosli attest generic + --name tf-apply-plan-beta + --flow ${{ env.KOSLI_FLOW }} + --trail ${{ env.KOSLI_TRAIL }} + --attachments ./tfplan + --host ${{ env.KOSLI_HOST }} + --api-token ${{ secrets.KOSLI_API_TOKEN }} + + - name: Attest tf plan to Kosli trail (staging) + run: + kosli attest generic + --name tf-apply-plan-beta + --flow ${{ env.KOSLI_FLOW }} + --trail ${{ env.KOSLI_TRAIL }} + --attachments ./tfplan + --host ${{ env.KOSLI_HOST_STAGING }} + --api-token ${{ secrets.KOSLI_API_TOKEN_STAGING }} + + - name: Delete tf plan artifact + run: | + # Get the list of artifacts + artifact_id=$(curl -s -L \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${{ github.repository}}/actions/runs/${{ github.run_id }}/artifacts | jq -r '.artifacts[] | select(.name == "tf_artifacts_${{ matrix.environment }}").id') + + # Delete each artifact + curl -L \ + -X DELETE \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${{ github.repository}}/actions/artifacts/${artifact_id} + + - name: Attest tf state artifact (production) + run: | + kosli attest artifact \ + --artifact-type file ./${{ needs.variables.outputs.service_name }}.tfstate \ + --name state-beta \ + --flow ${{ env.KOSLI_FLOW }} \ + --trail ${{ env.KOSLI_TRAIL }} \ + --host ${{ env.KOSLI_HOST }} \ + --api-token ${{ secrets.KOSLI_API_TOKEN }} + + - name: Attest tf state artifact (staging) + run: | + kosli attest artifact \ + --artifact-type file ./${{ needs.variables.outputs.service_name }}.tfstate \ + --name state-beta \ + --flow ${{ env.KOSLI_FLOW }} \ + --trail ${{ env.KOSLI_TRAIL }} \ + --host ${{ env.KOSLI_HOST_STAGING }} \ + --api-token ${{ secrets.KOSLI_API_TOKEN_STAGING }} + + - name: Delete tf state file artifact + run: | + # Get the list of artifacts + artifact_id=$(curl -s -L \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${{ github.repository}}/actions/runs/${{ github.run_id }}/artifacts | jq -r '.artifacts[] | select(.name == "tf_artifacts_state_file_${{ matrix.environment }}").id') + + # Delete each artifact + curl -L \ + -X DELETE \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${{ github.repository}}/actions/artifacts/${artifact_id} diff --git a/.github/workflows/sub_deploy_to_prod.yml b/.github/workflows/sub_deploy_to_prod.yml new file mode 100644 index 0000000..919a6f0 --- /dev/null +++ b/.github/workflows/sub_deploy_to_prod.yml @@ -0,0 +1,193 @@ +name: Sub - deploy to aws-prod + +on: + workflow_call: + inputs: + IMAGE_TAG: + required: true + type: string + secrets: + KOSLI_API_TOKEN_STAGING: + required: true + KOSLI_API_TOKEN: + required: true + + +env: + KOSLI_ORG: cyber-dojo + KOSLI_FLOW: languages-start-points-ci + KOSLI_TRAIL: ${{ github.sha }} + KOSLI_HOST: "https://app.kosli.com" + KOSLI_HOST_STAGING: "https://staging.app.kosli.com" + +jobs: + + variables: + runs-on: ubuntu-latest + outputs: + service_name: ${{ steps.vars.outputs.service_name }} + image_tag: ${{ steps.vars.outputs.image_tag }} + aws_account_id: ${{ steps.vars.outputs.aws_account_id }} + ecr_registry: ${{ steps.vars.outputs.ecr_registry }} + aws_region: ${{ steps.vars.outputs.aws_region }} + gh_actions_iam_role_name: ${{ steps.vars.outputs.gh_actions_iam_role_name }} + steps: + - name: Prepare outputs for fivexl deployment workflow + id: vars + run: | + echo "service_name=languages-start-points" >> ${GITHUB_OUTPUT} + echo "image_tag=${{ inputs.IMAGE_TAG }}" >> ${GITHUB_OUTPUT} + echo "aws_account_id=274425519734" >> ${GITHUB_OUTPUT} + echo "ecr_registry=274425519734.dkr.ecr.eu-central-1.amazonaws.com" >> ${GITHUB_OUTPUT} + echo "aws_region=eu-central-1" >> ${GITHUB_OUTPUT} + echo "gh_actions_iam_role_name=gh_actions_services" >> ${GITHUB_OUTPUT} + + push-image-to-prod-ecr: + needs: [variables] + runs-on: ubuntu-latest + permissions: + id-token: write + contents: write + steps: + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ needs.variables.outputs.aws_region }} + role-duration-seconds: 2400 + role-session-name: ${{ github.event.repository.name }} + role-to-assume: arn:aws:iam::${{ needs.variables.outputs.aws_account_id }}:role/${{ needs.variables.outputs.gh_actions_iam_role_name }} + + - name: Login to Amazon ECR (Elastic Container Registry) + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + + - name: Push image to private prod-ECR + run: | + PUBLIC_IMAGE_NAME=cyberdojo/${{ needs.variables.outputs.service_name }}:${{ inputs.IMAGE_TAG }} + PRIVATE_IMAGE_NAME=${{ needs.variables.outputs.ecr_registry }}/${{ needs.variables.outputs.service_name }}:${{ inputs.IMAGE_TAG }} + docker pull ${PUBLIC_IMAGE_NAME} + docker tag ${PUBLIC_IMAGE_NAME} ${PRIVATE_IMAGE_NAME} + docker push ${PRIVATE_IMAGE_NAME} + + deploy-to-aws-prod: + needs: [variables, push-image-to-prod-ecr] + permissions: + id-token: write + contents: write + uses: fivexl/gh-workflow-tf-plan-apply/.github/workflows/base.yml@v0.0.18 + with: + aws_region: ${{ needs.variables.outputs.aws_region }} + aws_role_arn: arn:aws:iam::${{ needs.variables.outputs.aws_account_id }}:role/${{ needs.variables.outputs.gh_actions_iam_role_name }} + aws_default_region: ${{ needs.variables.outputs.aws_region }} + aws_role_duration: 900 + working_directory: deployment/terraform/ + tf_apply: 'true' + tf_version: v1.4.5 + tf_additional_env_vars: '{"TF_VAR_TAGGED_IMAGE": "${{ needs.variables.outputs.ecr_registry }}/${{ needs.variables.outputs.service_name }}:${{ needs.variables.outputs.image_tag }}"}' +# tf_sh_version: 0.2.1 +# tf_upload_artifact_name_suffix: "_prod" +# tf_upload_artifact_state_file: 'true' +# tf_upload_artifact_plan: 'true' +# tf_state_file_dir_on_s3: "terraform/${{ needs.variables.outputs.service_name }}" +# tf_state_file_name: "${{ needs.variables.outputs.service_name }}.tfstate" + + trail-attest-terraform: + needs: deploy-to-aws-prod + if: false # WIP + permissions: + actions: write + contents: read + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup kosli cli + uses: kosli-dev/setup-cli-action@v2 + with: + version: + ${{ vars.KOSLI_CLI_VERSION }} + + - name: Download a plan artifact + uses: actions/download-artifact@v4.1.1 + with: + name: tf_artifacts_plan_prod + + - name: Download a state file artifact + uses: actions/download-artifact@v4.1.1 + with: + name: tf_artifacts_state_file_prod + + - name: Attest tf plan to Kosli trail (production) + run: + kosli attest generic + --name tf-apply-plan-prod + --flow ${{ env.KOSLI_FLOW }} + --trail ${{ env.KOSLI_TRAIL }} + --attachments ./tfplan + --host ${{ env.KOSLI_HOST }} + --api-token ${{ secrets.KOSLI_API_TOKEN }} + + - name: Attest tf plan to Kosli trail (staging) + run: + kosli attest generic + --name tf-apply-plan-prod + --flow ${{ env.KOSLI_FLOW }} + --trail ${{ env.KOSLI_TRAIL }} + --attachments ./tfplan + --host ${{ env.KOSLI_HOST_STAGING }} + --api-token ${{ secrets.KOSLI_API_TOKEN_STAGING }} + + - name: Delete tf plan artifact + run: | + # Get the list of artifacts + artifact_id=$(curl -s -L \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${{ github.repository}}/actions/runs/${{ github.run_id }}/artifacts | jq -r '.artifacts[] | select(.name == "tf_artifacts_${{ matrix.environment }}").id') + + # Delete each artifact + curl -L \ + -X DELETE \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${{ github.repository}}/actions/artifacts/${artifact_id} + + - name: Attest tf state artifact (production) + run: | + kosli attest artifact \ + --artifact-type file ./${{ needs.variables.outputs.service_name }}.tfstate \ + --name state-prod \ + --flow ${{ env.KOSLI_FLOW }} \ + --trail ${{ env.KOSLI_TRAIL }} \ + --host ${{ env.KOSLI_HOST }} \ + --api-token ${{ secrets.KOSLI_API_TOKEN }} + + - name: Attest tf state artifact (staging) + run: | + kosli attest artifact \ + --artifact-type file ./${{ needs.variables.outputs.service_name }}.tfstate \ + --name state-prod \ + --flow ${{ env.KOSLI_FLOW }} \ + --trail ${{ env.KOSLI_TRAIL }} \ + --host ${{ env.KOSLI_HOST_STAGING }} \ + --api-token ${{ secrets.KOSLI_API_TOKEN_STAGING }} + + - name: Delete tf state file artifact + run: | + # Get the list of artifacts + artifact_id=$(curl -s -L \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${{ github.repository}}/actions/runs/${{ github.run_id }}/artifacts | jq -r '.artifacts[] | select(.name == "tf_artifacts_state_file_${{ matrix.environment }}").id') + + # Delete each artifact + curl -L \ + -X DELETE \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${{ github.repository}}/actions/artifacts/${artifact_id} diff --git a/.kosli.yml b/.kosli.yml index 435280c..5ce984e 100644 --- a/.kosli.yml +++ b/.kosli.yml @@ -4,5 +4,7 @@ trail: artifacts: - name: languages-start-points attestations: - - name: snyk-scan + - name: snyk-container-scan + type: snyk + - name: snyk-code-scan type: snyk diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2cabe68 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ + +SHORT_SHA := $(shell git rev-parse HEAD | head -c7) +IMAGE_NAME := cyberdojo/languages-start-points:${SHORT_SHA} + +.PHONY: image snyk-container snyk-code + +image: + ${PWD}/sh/build_test_tag.sh + +snyk-container: image + snyk container test ${IMAGE_NAME} \ + --file=Dockerfile \ + --sarif \ + --sarif-file-output=snyk.container.scan.json \ + --policy-path=.snyk + +snyk-code: + snyk code test \ + --sarif \ + --sarif-file-output=snyk.code.scan.json \ + --policy-path=.snyk + diff --git a/README.md b/README.md index a214e49..a6b4f31 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,12 @@ -- Run the script [sh/update_image_lists.sh](https://github.com/cyber-dojo/languages-start-points/blob/master/sh/update_image_lists.sh) after adding any new urls, to create up to date versions of the two image list files: +- Add any new urls to ALL_URLS in [sh/update_image_lists.sh](https://github.com/cyber-dojo/languages-start-points/blob/master/sh/update_image_lists.sh) +- Run the script [sh/update_image_lists.sh](https://github.com/cyber-dojo/languages-start-points/blob/master/sh/update_image_lists.sh) to create up-to-date versions of the two image list files: - [git_repo_urls.tagged](https://github.com/cyber-dojo/languages-start-points/blob/master/git_repo_urls.tagged) lists all the language-test-framework repositories (each repo contributes one `manifest.json`) to the image. - [compressed.image_sizes.sorted](https://github.com/cyber-dojo/languages-start-points/blob/master/compressed.image_sizes.sorted) lists all the images named in these `manifest.json` files, together with their (compressed) sizes, in descending order. Informational only. -- Run the script [build_test_publish.sh](https://github.com/cyber-dojo/languages-start-points/blob/master/build_test_publish.sh) to build the image if you are working locally. +- Run the `make image` to build the image from `git_repo_urls.tagged`. - Commit and push. The resulting image's dockerhub registry is [cyberdojo/languages-start-points](https://hub.docker.com/r/cyberdojo/languages-start-points/tags) diff --git a/build_test.sh b/build_test.sh new file mode 100755 index 0000000..642385a --- /dev/null +++ b/build_test.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -Eeu + +make image \ No newline at end of file diff --git a/docs/snapshot.json b/docs/snapshot.json new file mode 100644 index 0000000..e6c5d5b --- /dev/null +++ b/docs/snapshot.json @@ -0,0 +1,401 @@ +{ + "index": 1138, + "is_latest": true, + "next_snapshot_timestamp": null, + "artifact_compliance_count": { + "true": 5, + "false": 6 + }, + "timestamp": 1697084697.301973, + "type": "ECS", + "compliant": false, + "html_url": "https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/1138", + "artifacts": [ + { + "name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/differ:44e6c27", + "compliant": false, + "deployments": [ + 178 + ], + "reasons_for_incompliance": [ + { + "type": "failing_evidence", + "message": "Artifact has failed evidence for snyk-scan" + } + ], + "fingerprint": "c6cd1a5b122d88aaeb41c1fdd015ad88c2bea95ae85f63eb5544fb707254847e", + "creationTimestamp": [ + 1696223791 + ], + "pods": null, + "annotation": { + "type": "changed", + "was": 1, + "now": 1 + }, + "flow_name": "differ", + "git_commit": "44e6c271b46a56acd07f3b426c6cbca393442bb4", + "commit_url": "https://github.com/cyber-dojo/differ/commit/44e6c271b46a56acd07f3b426c6cbca393442bb4", + "html_url": "https://app.kosli.com/cyber-dojo/flows/differ/artifacts/c6cd1a5b122d88aaeb41c1fdd015ad88c2bea95ae85f63eb5544fb707254847e", + "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/differ", + "deployment_diff": { + "diff_url": "https://github.com/cyber-dojo/differ/compare/d57890ea81dfa1b045f298c45818ed89078e0c42...44e6c271b46a56acd07f3b426c6cbca393442bb4", + "previous_git_commit": "d57890ea81dfa1b045f298c45818ed89078e0c42", + "previous_fingerprint": "708c5c4c6c4291f91117384b0de5ba6fc06bd0c237618dc690929d345aa67a50", + "previous_artifact_name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/differ:d57890e", + "previous_artifact_compliance_state": "COMPLIANT", + "previous_running": false + }, + "commit_lead_time": "401" + }, + { + "name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/runner:4a90753", + "compliant": true, + "deployments": [ + 50 + ], + "reasons_for_incompliance": [], + "fingerprint": "c48f0821fb1f5460cdc8884fa124d66cd51b2e671448c897be02f0529042c1fd", + "creationTimestamp": [ + 1697060662, + 1697060663, + 1697060666 + ], + "pods": null, + "annotation": { + "type": "unchanged", + "was": 3, + "now": 3 + }, + "flow_name": "runner", + "git_commit": "4a907536be7f7f17440e7b69cea64e76ee85a991", + "commit_url": "https://github.com/cyber-dojo/runner/commit/4a907536be7f7f17440e7b69cea64e76ee85a991", + "html_url": "https://app.kosli.com/cyber-dojo/flows/runner/artifacts/c48f0821fb1f5460cdc8884fa124d66cd51b2e671448c897be02f0529042c1fd", + "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/runner", + "deployment_diff": { + "diff_url": "https://github.com/cyber-dojo/runner/compare/5f1f3cad8f7fd4ada231277b81ef3cfb92aa7ee6...4a907536be7f7f17440e7b69cea64e76ee85a991", + "previous_git_commit": "5f1f3cad8f7fd4ada231277b81ef3cfb92aa7ee6", + "previous_fingerprint": "86e8dc5ae27ab00f390f241285668be7599b84fce7b80220833feb6717596007", + "previous_artifact_name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/runner:5f1f3ca", + "previous_artifact_compliance_state": "NON-COMPLIANT", + "previous_running": false + }, + "commit_lead_time": "396" + }, + { + "name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/exercises-start-points:f6ae20a", + "compliant": true, + "deployments": [ + 62 + ], + "reasons_for_incompliance": [], + "fingerprint": "c15ee66eb77cca91939c40a71ed2c0b7597a7fd4756d035dec3417c595242078", + "creationTimestamp": [ + 1697060231 + ], + "pods": null, + "annotation": { + "type": "unchanged", + "was": 1, + "now": 1 + }, + "flow_name": "exercises-start-points", + "git_commit": "f6ae20a8db68ec187c937f85736e2dca8f6a0fbf", + "commit_url": "https://github.com/cyber-dojo/exercises-start-points/commit/f6ae20a8db68ec187c937f85736e2dca8f6a0fbf", + "html_url": "https://app.kosli.com/cyber-dojo/flows/exercises-start-points/artifacts/c15ee66eb77cca91939c40a71ed2c0b7597a7fd4756d035dec3417c595242078", + "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/exercises-start-points", + "deployment_diff": { + "diff_url": "https://github.com/cyber-dojo/exercises-start-points/compare/8032bee72e64f77e059049154a2555610bf58da2...f6ae20a8db68ec187c937f85736e2dca8f6a0fbf", + "previous_git_commit": "8032bee72e64f77e059049154a2555610bf58da2", + "previous_fingerprint": "da4354893537dbb1f992c2f3285d9d3db66584b56eb91f311257be7a50d6f37c", + "previous_artifact_name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/exercises-start-points:8032bee", + "previous_artifact_compliance_state": "NON-COMPLIANT", + "previous_running": false + }, + "commit_lead_time": "215" + }, + { + "name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/custom-start-points:72d4df2", + "compliant": true, + "deployments": [ + 42 + ], + "reasons_for_incompliance": [], + "fingerprint": "a27c79318134ad4c522941d723f1cd42d440f2c82ea154c44f7e28eff681480c", + "creationTimestamp": [ + 1697060135 + ], + "pods": null, + "annotation": { + "type": "unchanged", + "was": 1, + "now": 1 + }, + "flow_name": "custom-start-points", + "git_commit": "72d4df2caf620c5069adff276d9f5e07590e8d0e", + "commit_url": "https://github.com/cyber-dojo/custom-start-points/commit/72d4df2caf620c5069adff276d9f5e07590e8d0e", + "html_url": "https://app.kosli.com/cyber-dojo/flows/custom-start-points/artifacts/a27c79318134ad4c522941d723f1cd42d440f2c82ea154c44f7e28eff681480c", + "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/custom-start-points", + "deployment_diff": { + "diff_url": "https://github.com/cyber-dojo/custom-start-points/compare/634f1cdea2d1cf8f8aeec91e757b73755e901107...72d4df2caf620c5069adff276d9f5e07590e8d0e", + "previous_git_commit": "634f1cdea2d1cf8f8aeec91e757b73755e901107", + "previous_fingerprint": "5501d3697454fb0117436372109006216fd6a968d4bdf9c4d857fb089d44d1c0", + "previous_artifact_name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/custom-start-points:634f1cd", + "previous_artifact_compliance_state": "NON-COMPLIANT", + "previous_running": false + }, + "commit_lead_time": "252" + }, + { + "name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/languages-start-points:3ef8797", + "compliant": true, + "deployments": [ + 69 + ], + "reasons_for_incompliance": [], + "fingerprint": "ea2aa706b3a6aa2c891263651d4d7c05519ee04e77c61828ea4761fdcfa47c90", + "creationTimestamp": [ + 1697060099 + ], + "pods": null, + "annotation": { + "type": "unchanged", + "was": 1, + "now": 1 + }, + "flow_name": "languages-start-points", + "git_commit": "3ef87970efb48c2e5f8c164045736014e6431cf9", + "commit_url": "https://github.com/cyber-dojo/languages-start-points/commit/3ef87970efb48c2e5f8c164045736014e6431cf9", + "html_url": "https://app.kosli.com/cyber-dojo/flows/languages-start-points/artifacts/ea2aa706b3a6aa2c891263651d4d7c05519ee04e77c61828ea4761fdcfa47c90", + "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/languages-start-points", + "deployment_diff": { + "diff_url": "https://github.com/cyber-dojo/languages-start-points/compare/a9b50ce5a4bde756ac3e9d07ff13eb147ace41b5...3ef87970efb48c2e5f8c164045736014e6431cf9", + "previous_git_commit": "a9b50ce5a4bde756ac3e9d07ff13eb147ace41b5", + "previous_fingerprint": "ef49c9f5a970e2781cd2207483a1df1e70a94165175f9ebc3e644bc7d12a1577", + "previous_artifact_name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/languages-start-points:a9b50ce", + "previous_artifact_compliance_state": "NON-COMPLIANT", + "previous_running": false + }, + "commit_lead_time": "269" + }, + { + "name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/nginx:b1ff2f7", + "compliant": true, + "deployments": [ + 74 + ], + "reasons_for_incompliance": [], + "fingerprint": "6442cf22ccba72a98e68d772c38c2cfb2492e5a34ad4cf68f6f0e69694d5b00a", + "creationTimestamp": [ + 1697053353 + ], + "pods": null, + "annotation": { + "type": "unchanged", + "was": 1, + "now": 1 + }, + "flow_name": "nginx", + "git_commit": "b1ff2f75f55fdf8733de82f22b529b6d9cac37fb", + "commit_url": "https://github.com/cyber-dojo/nginx/commit/b1ff2f75f55fdf8733de82f22b529b6d9cac37fb", + "html_url": "https://app.kosli.com/cyber-dojo/flows/nginx/artifacts/6442cf22ccba72a98e68d772c38c2cfb2492e5a34ad4cf68f6f0e69694d5b00a", + "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/nginx", + "deployment_diff": { + "diff_url": "https://github.com/cyber-dojo/nginx/compare/4f9e4552ae594505e3250729299b4c6dcf864fdc...b1ff2f75f55fdf8733de82f22b529b6d9cac37fb", + "previous_git_commit": "4f9e4552ae594505e3250729299b4c6dcf864fdc", + "previous_fingerprint": "b9d5301dfc6d329ed547a6751a7fded2bf5965793361b8a24e2910f220039e24", + "previous_artifact_name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/nginx:4f9e455", + "previous_artifact_compliance_state": "NON-COMPLIANT", + "previous_running": false + }, + "commit_lead_time": "525" + }, + { + "name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/shas:81ab491", + "compliant": false, + "deployments": [ + 59 + ], + "reasons_for_incompliance": [ + { + "type": "failing_evidence", + "message": "Artifact has failed evidence for snyk-scan" + } + ], + "fingerprint": "eaa2885bdceaeb49372ec734bab19f5e3e2d1ce59661fe6f97ad2d10ee39a8b0", + "creationTimestamp": [ + 1697015681 + ], + "pods": null, + "annotation": { + "type": "unchanged", + "was": 1, + "now": 1 + }, + "flow_name": "shas", + "git_commit": "81ab49132e118a98b5c2e3f9e447a6bc3a472379", + "commit_url": "https://github.com/cyber-dojo/shas/commit/81ab49132e118a98b5c2e3f9e447a6bc3a472379", + "html_url": "https://app.kosli.com/cyber-dojo/flows/shas/artifacts/eaa2885bdceaeb49372ec734bab19f5e3e2d1ce59661fe6f97ad2d10ee39a8b0", + "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/shas", + "deployment_diff": { + "diff_url": "https://github.com/cyber-dojo/shas/compare/57f22c0cb57617fe123f7eb6044094973720fac9...81ab49132e118a98b5c2e3f9e447a6bc3a472379", + "previous_git_commit": "57f22c0cb57617fe123f7eb6044094973720fac9", + "previous_fingerprint": "16654336918ed7305eafa04cbe1ae548d44ad2549629e216606b41e1af586594", + "previous_artifact_name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/shas:57f22c0", + "previous_artifact_compliance_state": "COMPLIANT", + "previous_running": false + }, + "commit_lead_time": "278" + }, + { + "name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/web:a6d085f", + "compliant": false, + "deployments": [ + 91 + ], + "reasons_for_incompliance": [ + { + "type": "failing_evidence", + "message": "Artifact has failed evidence for snyk-scan" + } + ], + "fingerprint": "7ef0a70593852064b16c4cc36800551f0776c030eca8f5265669ddb7a8cebbaf", + "creationTimestamp": [ + 1696306052, + 1696306052, + 1696306052 + ], + "pods": null, + "annotation": { + "type": "unchanged", + "was": 3, + "now": 3 + }, + "flow_name": "web", + "git_commit": "a6d085f22f1ba4c4097d1dd1086a0ed3b6703641", + "commit_url": "https://github.com/cyber-dojo/web/commit/a6d085f22f1ba4c4097d1dd1086a0ed3b6703641", + "html_url": "https://app.kosli.com/cyber-dojo/flows/web/artifacts/7ef0a70593852064b16c4cc36800551f0776c030eca8f5265669ddb7a8cebbaf", + "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/web", + "deployment_diff": { + "diff_url": "https://github.com/cyber-dojo/web/compare/692d666283c7bfcd63b5f8e93a38e7085d61a535...a6d085f22f1ba4c4097d1dd1086a0ed3b6703641", + "previous_git_commit": "692d666283c7bfcd63b5f8e93a38e7085d61a535", + "previous_fingerprint": "a2fea9dda99de527da5400b4921c3f93953d977e00077442bf095942c0dc85d7", + "previous_artifact_name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/web:692d666", + "previous_artifact_compliance_state": "COMPLIANT", + "previous_running": false + }, + "commit_lead_time": "865" + }, + { + "name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/saver:4d23f0e", + "compliant": false, + "deployments": [ + 167 + ], + "reasons_for_incompliance": [ + { + "type": "failing_evidence", + "message": "Artifact has failed evidence for snyk-scan" + } + ], + "fingerprint": "45a9896337df0f39e47111eab7c01f412bad1c685732b9b97e4c0ee1c94db0fa", + "creationTimestamp": [ + 1696225006 + ], + "pods": null, + "annotation": { + "type": "unchanged", + "was": 1, + "now": 1 + }, + "flow_name": "saver", + "git_commit": "4d23f0e8c867d09518b0a96ec76859feb0d7a82e", + "commit_url": "https://github.com/cyber-dojo/saver/commit/4d23f0e8c867d09518b0a96ec76859feb0d7a82e", + "html_url": "https://app.kosli.com/cyber-dojo/flows/saver/artifacts/45a9896337df0f39e47111eab7c01f412bad1c685732b9b97e4c0ee1c94db0fa", + "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/saver", + "deployment_diff": { + "diff_url": "https://github.com/cyber-dojo/saver/compare/d637b4b9d2d929f9a0accbae0ab8795897222240...4d23f0e8c867d09518b0a96ec76859feb0d7a82e", + "previous_git_commit": "d637b4b9d2d929f9a0accbae0ab8795897222240", + "previous_fingerprint": "2224a97de2160f0c8c14d450d817da2587180a929d45afcfa868e88223a2c021", + "previous_artifact_name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/saver:d637b4b", + "previous_artifact_compliance_state": "COMPLIANT", + "previous_running": false + }, + "commit_lead_time": "1867" + }, + { + "name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/creator:1afdb47", + "compliant": false, + "deployments": [ + 232 + ], + "reasons_for_incompliance": [ + { + "type": "failing_evidence", + "message": "Artifact has failed evidence for snyk-scan" + } + ], + "fingerprint": "243e8efaeb41bc687d0c177f114ecdf10afeeef6426f55efcb897081da369edc", + "creationTimestamp": [ + 1696224065 + ], + "pods": null, + "annotation": { + "type": "unchanged", + "was": 1, + "now": 1 + }, + "flow_name": "creator", + "git_commit": "1afdb47a2b4256cadea4b5ac1a6e1e0ac81b8f5e", + "commit_url": "https://github.com/cyber-dojo/creator/commit/1afdb47a2b4256cadea4b5ac1a6e1e0ac81b8f5e", + "html_url": "https://app.kosli.com/cyber-dojo/flows/creator/artifacts/243e8efaeb41bc687d0c177f114ecdf10afeeef6426f55efcb897081da369edc", + "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/creator", + "deployment_diff": { + "diff_url": "https://github.com/cyber-dojo/creator/compare/6746e511d05485812afaa231fab26a53b094ae95...1afdb47a2b4256cadea4b5ac1a6e1e0ac81b8f5e", + "previous_git_commit": "6746e511d05485812afaa231fab26a53b094ae95", + "previous_fingerprint": "b1a0ac824b5448244fea2fee2fa1cfcfc77acbb87331d02f2ddf82ecf3ad3d27", + "previous_artifact_name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/creator:6746e51", + "previous_artifact_compliance_state": "COMPLIANT", + "previous_running": false + }, + "commit_lead_time": "364" + }, + { + "name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/dashboard:5cee400", + "compliant": false, + "deployments": [ + 46 + ], + "reasons_for_incompliance": [ + { + "type": "failing_evidence", + "message": "Artifact has failed evidence for snyk-scan" + } + ], + "fingerprint": "5e5fe53a9f330552c9509adc3c6b8db38323e165c9307f0be1a515f5a562b405", + "creationTimestamp": [ + 1696223924 + ], + "pods": null, + "annotation": { + "type": "unchanged", + "was": 1, + "now": 1 + }, + "flow_name": "dashboard", + "git_commit": "5cee400e2df410479b8118fca4956aea33ac8fe9", + "commit_url": "https://github.com/cyber-dojo/dashboard/commit/5cee400e2df410479b8118fca4956aea33ac8fe9", + "html_url": "https://app.kosli.com/cyber-dojo/flows/dashboard/artifacts/5e5fe53a9f330552c9509adc3c6b8db38323e165c9307f0be1a515f5a562b405", + "flow_html_url": "https://app.kosli.com/cyber-dojo/flows/dashboard", + "deployment_diff": { + "diff_url": "https://github.com/cyber-dojo/dashboard/compare/7d0dd9b4f06af7c57507530d2fa93ce229c8598e...5cee400e2df410479b8118fca4956aea33ac8fe9", + "previous_git_commit": "7d0dd9b4f06af7c57507530d2fa93ce229c8598e", + "previous_fingerprint": "d89112951e9eed696013f27f1b38f1e33d72cec801dcddf147ad7be645da2111", + "previous_artifact_name": "274425519734.dkr.ecr.eu-central-1.amazonaws.com/dashboard:7d0dd9b", + "previous_artifact_compliance_state": "COMPLIANT", + "previous_running": false + }, + "commit_lead_time": "300" + } + ] +} diff --git a/sh/build_test_tag.sh b/sh/build_test_tag.sh new file mode 100755 index 0000000..dce35a2 --- /dev/null +++ b/sh/build_test_tag.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +set -Eeu + +repo_root() { git rev-parse --show-toplevel; } + +readonly SH_DIR="$(repo_root)/sh" +readonly TMP_DIR=$(mktemp -d /tmp/cyber-dojo.languages-start-points.XXXXXXXXX) +trap "rm -rf ${TMP_DIR} > /dev/null" INT EXIT +source "${SH_DIR}/lib.sh" +source "${SH_DIR}/echo_versioner_env_vars.sh" +export $(echo_versioner_env_vars) + +# - - - - - - - - - - - - - - - - - - - - - - - - +build_test_tag() +{ + local -r image=cyberdojo/languages-start-points + local -r names="$(cat "$(repo_root)/git_repo_urls.tagged" | tr '\n' ' ')" + + # build + export GIT_COMMIT_SHA="$(git_commit_sha)" + $(cyber_dojo) start-point create "$(image_name)" --languages "${names}" + unset GIT_COMMIT_SHA + + # test + assert_equal "$(git_commit_sha)" "$(image_sha)" + + # tag + docker tag "$(image_name):latest" "$(image_name):$(git_commit_tag)" + echo "tagged with :$(git_commit_tag)" +} + + +# - - - - - - - - - - - - - - - - - - - - - - - - +assert_equal() +{ + local -r expected="${1}" + local -r actual="${2}" + if [ "${expected}" != "${actual}" ]; then + echo ERROR + echo "expected:'${expected}'" + echo " actual:'${actual}'" + exit 42 + fi +} + +# - - - - - - - - - - - - - - - - - - - - - - - - +cyber_dojo() +{ + local -r name=cyber-dojo + if [ -x "$(command -v ${name})" ]; then + >&2 echo "Found executable ${name} on the PATH" + echo "${name}" + else + local -r url="https://raw.githubusercontent.com/cyber-dojo/commander/master/${name}" + >&2 echo "Did not find executable ${name} on the PATH" + >&2 echo "Curling it from ${url}" + curl --fail --output "${TMP_DIR}/${name}" --silent "${url}" + chmod 700 "${TMP_DIR}/${name}" + echo "${TMP_DIR}/${name}" + fi +} + +# - - - - - - - - - - - - - - - - - - - - - - - - +build_test_tag diff --git a/build_test_publish.sh b/sh/dead/build_test_publish.sh similarity index 95% rename from build_test_publish.sh rename to sh/dead/build_test_publish.sh index 2b32582..5dd5c5f 100755 --- a/build_test_publish.sh +++ b/sh/dead/build_test_publish.sh @@ -4,6 +4,7 @@ readonly ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" readonly SH_DIR="${ROOT_DIR}/sh" readonly TMP_DIR=$(mktemp -d /tmp/cyber-dojo.languages-start-points.XXXXXXXXX) trap "rm -rf ${TMP_DIR} > /dev/null" INT EXIT +source "${SH_DIR}/lib.sh" source "${SH_DIR}/echo_versioner_env_vars.sh" export $(echo_versioner_env_vars) source "${SH_DIR}/kosli.sh" @@ -58,12 +59,6 @@ cyber_dojo() fi } -# - - - - - - - - - - - - - - - - - - - - - - - - -on_ci() -{ - [ -n "${CI:-}" ] -} - # - - - - - - - - - - - - - - - - - - - - - - - - on_ci_kosli_begin_trail build_test_tag diff --git a/sh/kosli.sh b/sh/dead/kosli.sh similarity index 95% rename from sh/kosli.sh rename to sh/dead/kosli.sh index c7df65e..39b89c0 100755 --- a/sh/kosli.sh +++ b/sh/dead/kosli.sh @@ -78,18 +78,6 @@ artifact_name() echo "${CYBER_DOJO_LANGUAGES_START_POINTS_IMAGE}:${CYBER_DOJO_LANGUAGES_START_POINTS_TAG}" } -# - - - - - - - - - - - - - - - - - - - -repo_root() -{ - git rev-parse --show-toplevel -} - -# - - - - - - - - - - - - - - - - - - - - - - - - -on_ci() -{ - [ -n "${CI:-}" ] -} - # - - - - - - - - - - - - - - - - - - - on_ci_kosli_begin_trail() { diff --git a/sh/dead/main.yml b/sh/dead/main.yml new file mode 100644 index 0000000..9213431 --- /dev/null +++ b/sh/dead/main.yml @@ -0,0 +1,71 @@ +name: Main + +on: + push: + branches: + - main + +jobs: + pre-build: + runs-on: ubuntu-latest + outputs: + image_tag: ${{ steps.prep.outputs.image_tag }} + steps: + - uses: actions/checkout@v3 + - name: Prepare + id: prep + run: | + TAG=$(echo $GITHUB_SHA | head -c7) + echo "image_tag=${TAG}" >> ${GITHUB_OUTPUT} + + build-test-push: + needs: [pre-build] + uses: cyber-dojo/reusable-actions-workflows/.github/workflows/kosli_build_test_push.yml@v0.0.11 + secrets: + KOSLI_API_TOKEN: ${{ secrets.KOSLI_API_TOKEN }} + KOSLI_API_TOKEN_STAGING: ${{ secrets.KOSLI_API_TOKEN_STAGING }} + DOCKER_PASS: ${{ secrets.DOCKER_PASS }} + DOCKER_USER: ${{ secrets.DOCKER_USER }} + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + with: + BUILD_COMMAND: build_test_publish.sh + image_tag: ${{ needs.pre-build.outputs.image_tag }} + AWS_ACCOUNT_ID: 244531986313 + AWS_REGION: eu-central-1 + ecr_registry: 244531986313.dkr.ecr.eu-central-1.amazonaws.com + service_name: languages-start-points + gh_actions_iam_role_name: gh_actions_services + + deploy-staging: + needs: [pre-build, build-test-push] + uses: cyber-dojo/reusable-actions-workflows/.github/workflows/kosli_deploy.yml@v0.0.11 + secrets: + KOSLI_API_TOKEN: ${{ secrets.KOSLI_API_TOKEN }} + KOSLI_API_TOKEN_STAGING: ${{ secrets.KOSLI_API_TOKEN_STAGING }} + with: + tagged_image: 244531986313.dkr.ecr.eu-central-1.amazonaws.com/languages-start-points:${{ needs.pre-build.outputs.image_tag }} + AWS_ACCOUNT_ID: 244531986313 + AWS_REGION: eu-central-1 + gh_actions_iam_role_name: gh_actions_services + environment_url: https://beta.cyber-dojo.org + environment_name: staging + cyber_dojo_env_name_aws: aws-beta + kosli_host_staging: https://staging.app.kosli.com + kosli_host_production: https://app.kosli.com + + deploy-prod: + needs: [pre-build, build-test-push, deploy-staging] + uses: cyber-dojo/reusable-actions-workflows/.github/workflows/kosli_deploy.yml@v0.0.11 + secrets: + KOSLI_API_TOKEN: ${{ secrets.KOSLI_API_TOKEN }} + KOSLI_API_TOKEN_STAGING: ${{ secrets.KOSLI_API_TOKEN_STAGING }} + with: + tagged_image: 274425519734.dkr.ecr.eu-central-1.amazonaws.com/languages-start-points:${{ needs.pre-build.outputs.image_tag }} + AWS_ACCOUNT_ID: 274425519734 + AWS_REGION: eu-central-1 + gh_actions_iam_role_name: gh_actions_services + environment_url: https://cyber-dojo.org + environment_name: production + cyber_dojo_env_name_aws: aws-prod + kosli_host_staging: https://staging.app.kosli.com + kosli_host_production: https://app.kosli.com diff --git a/sh/echo_versioner_env_vars.sh b/sh/echo_versioner_env_vars.sh index 2f94a52..9f6496e 100755 --- a/sh/echo_versioner_env_vars.sh +++ b/sh/echo_versioner_env_vars.sh @@ -1,6 +1,6 @@ -#!/bin/bash -Eeu +#!/usr/bin/env bash +set -Eeu -# - - - - - - - - - - - - - - - - - - - - - - - - echo_versioner_env_vars() { docker run --rm cyberdojo/versioner:latest @@ -8,35 +8,3 @@ echo_versioner_env_vars() echo CYBER_DOJO_LANGUAGES_START_POINTS_SHA="$(git_commit_sha)" echo CYBER_DOJO_LANGUAGES_START_POINTS_TAG="$(git_commit_tag)" } - -# - - - - - - - - - - - - - - - - - - - - - - - - -git_commit_sha() -{ - echo "$(cd "$(root_dir)" && git rev-parse HEAD)" -} - -# - - - - - - - - - - - - - - - - - - - - - - - - -git_commit_tag() -{ - local -r sha="$(git_commit_sha)" - echo "${sha:0:7}" -} - -# - - - - - - - - - - - - - - - - - - - - - - - - -image_name() -{ - echo "${CYBER_DOJO_LANGUAGES_START_POINTS_IMAGE}" -} - -# - - - - - - - - - - - - - - - - - - - - - - - - -image_sha() -{ - docker run --rm $(image_name) sh -c 'echo ${SHA}' -} - -root_dir() -{ - # Functions in this file are called after sourcing (not including) - # this file so root_dir() cannot use the path of this script. - git rev-parse --show-toplevel -} \ No newline at end of file diff --git a/sh/lib.sh b/sh/lib.sh new file mode 100755 index 0000000..fa02742 --- /dev/null +++ b/sh/lib.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -Eeu + +git_commit_sha() +{ + git rev-parse HEAD +} + +git_commit_tag() +{ + local -r sha="$(git_commit_sha)" + echo "${sha:0:7}" +} + +image_name() +{ + # set in + # export $(echo_versioner_env_vars) + echo "${CYBER_DOJO_LANGUAGES_START_POINTS_IMAGE}" +} + +image_sha() +{ + docker run --rm $(image_name) sh -c 'echo ${SHA}' +} diff --git a/sh/update_image_lists.sh b/sh/update_image_lists.sh index 93aacd5..184933b 100755 --- a/sh/update_image_lists.sh +++ b/sh/update_image_lists.sh @@ -1,4 +1,5 @@ -#!/bin/bash -Eeu +#!/usr/bin/env bash +set -Eeu readonly MY_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" readonly TMP_DIR=$(mktemp -d /tmp/cyber-dojo.languages-start-points.build.XXXXXX) diff --git a/sh/wait_for_deployment.sh b/sh/wait_for_deployment.sh new file mode 100755 index 0000000..b35accb --- /dev/null +++ b/sh/wait_for_deployment.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +set -Eu + +IMAGE_NAME="${1}" # eg cyberdojo/languages-start-points:6d650d5 +KOSLI_HOST="${2}" # eg https://app.kosli.com +KOSLI_API_TOKEN="${3}" # eg 7654y432er7132rwaefdgzfvdc (fake) +KOSLI_ORG="${4}" # eg cyber-dojo +KOSLI_ENVIRONMENT="${5}" # eg aws-prod + +image_deployed() +{ + local -r snapshot_json_filename=snapshot.json + + # Use Kosli CLI to get info on what artifacts are currently running + # (docs/snapshot.json contains an example json file) + echo "Getting snapshot from ${KOSLI_ENVIRONMENT} on ${KOSLI_HOST}" + + kosli get snapshot "${KOSLI_ENVIRONMENT}" \ + --host="${KOSLI_HOST}" \ + --api-token="${KOSLI_API_TOKEN}" \ + --org="${KOSLI_ORG}" \ + --output=json \ + > "${snapshot_json_filename}" + + # Process info, one artifact at a time + local -r artifacts_length=$(jq '.artifacts | length' ${snapshot_json_filename}) + for i in $(seq 0 $(( artifacts_length - 1 ))); + do + annotation_type=$(jq -r ".artifacts[$i].annotation.type" ${snapshot_json_filename}) + if [ "${annotation_type}" != "exited" ]; then + name=$(jq -r ".artifacts[$i].name" ${snapshot_json_filename}) + fingerprint=$(jq -r ".artifacts[$i].fingerprint" ${snapshot_json_filename}) + echo "Looking at Artifact ${name}" + if [ "${fingerprint}" == "${FINGERPRINT}" ]; then + echo "MATCHED: ${fingerprint} == ${FINGERPRINT}" + return 0 # true + else + echo "NO-MATCH ${fingerprint} != ${FINGERPRINT}" + fi + fi + done + return 1 # false +} + +image_not_deployed() +{ + local -r snapshot_json_filename=snapshot.json + echo "Failed!" + cat "${snapshot_json_filename}" +} + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +docker pull "${IMAGE_NAME}" +FINGERPRINT=$(kosli fingerprint "${IMAGE_NAME}" --artifact-type=docker) + +MAX_WAIT_TIME=$((8 * 60)) # max time to wait for image to be deployed +SLEEP_TIME=15 # wait time between deployment checks +MAX_ATTEMPTS=$(( MAX_WAIT_TIME / SLEEP_TIME )) +ATTEMPTS=1 + +until image_deployed +do + sleep 10 + [[ ${ATTEMPTS} -eq ${MAX_ATTEMPTS} ]] && image_not_deployed && exit 42 + ((ATTEMPTS++)) + echo "Waiting for deployment of Artifact ${IMAGE_NAME} to Environment ${KOSLI_ENVIRONMENT}" + echo "Attempt # ${ATTEMPTS} / ${MAX_ATTEMPTS}" +done +echo "Success: Artifact ${IMAGE_NAME} is running in Environment ${KOSLI_ENVIRONMENT}" +exit 0 diff --git a/sh/wait_for_image.sh b/sh/wait_for_image.sh new file mode 100755 index 0000000..f6f0cca --- /dev/null +++ b/sh/wait_for_image.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -Eu + +readonly IMAGE_NAME="${1}" # eg cyberdojo/languages-start-points:756c728 +readonly MAX_WAIT_TIME=5 # max time to wait for IMAGE_NAME to be pushed, in minutes +readonly SLEEP_TIME=10 # wait time between pull checks, in seconds +readonly MAX_ATTEMPTS=$(( MAX_WAIT_TIME * 60 / SLEEP_TIME )) + +ATTEMPTS=1 + +until docker pull "${IMAGE_NAME}" +do + sleep ${SLEEP_TIME} + [[ ${ATTEMPTS} -eq ${MAX_ATTEMPTS} ]] && echo "Failed!" && exit 1 + ((ATTEMPTS++)) + echo "Waiting for ${IMAGE_NAME} to be pushed to its registry" + echo "Attempt # ${ATTEMPTS} / ${MAX_ATTEMPTS}" +done +echo "Success: Artifact ${IMAGE_NAME} has been pushed to its registry" +exit 0