Merge pull request #2 from cyber-dojo/add-pull-request-to-kosli-sdlc-… #75
This file contains 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: 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: runner-ci | |
KOSLI_API_TOKEN: ${{ secrets.KOSLI_API_TOKEN }} | |
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="Test runner" | |
--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/runner:${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=runner.pull-request | |
lint: | |
needs: [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: Run Rubocop lint on source, attest evidence to Kosli Trail | |
env: | |
KOSLI_ATTACHMENTS: /tmp/kosli_attachments | |
run: | | |
mkdir -p "${KOSLI_ATTACHMENTS}" | |
set +e | |
make lint | tee "${KOSLI_ATTACHMENTS}"/rubocop.log | |
STATUS=${PIPESTATUS[0]} | |
set -e | |
KOSLI_COMPLIANT=$([ ${STATUS} = 0 ] && echo true || echo false) | |
cp .rubocop.yml "${KOSLI_ATTACHMENTS}" | |
kosli attest generic \ | |
--attachments="${KOSLI_ATTACHMENTS}" \ | |
--compliant="${KOSLI_COMPLIANT}" \ | |
--name=runner.lint | |
exit ${STATUS} | |
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 | |
- uses: docker/login-action@v3 | |
with: | |
username: ${{ secrets.DOCKER_USER }} | |
password: ${{ secrets.DOCKER_PASS }} | |
- name: Build and push image to Dockerhub Registry | |
uses: docker/build-push-action@v5 | |
with: | |
context: . | |
push: true | |
tags: ${{ needs.kosli-trail.outputs.image_name }} | |
build-args: | |
COMMIT_SHA=${{ github.sha }} | |
- 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=runner | |
--trail="${GITHUB_SHA}" | |
- name: Set outputs | |
id: variables | |
run: | | |
FINGERPRINT=$(kosli fingerprint "${IMAGE_NAME}" --artifact-type=docker) | |
echo "kosli_fingerprint=${FINGERPRINT}" >> ${GITHUB_OUTPUT} | |
unit-tests: | |
needs: [build-image, kosli-trail] | |
runs-on: ubuntu-latest | |
env: | |
IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} | |
KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.kosli_fingerprint }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Run unit tests with branch-coverage | |
run: | |
make unit_test | |
- name: Setup Kosli CLI | |
uses: kosli-dev/setup-cli-action@v2 | |
with: | |
version: ${{ vars.KOSLI_CLI_VERSION }} | |
- name: Attest results to Kosli | |
run: | | |
export REPORTS_DIR=./test/server/reports | |
kosli attest junit "${IMAGE_NAME}" \ | |
--name=runner.unit-test \ | |
--results-dir="${REPORTS_DIR}/junit" | |
kosli attest generic "${IMAGE_NAME}" \ | |
--attachments="${REPORTS_DIR}/coverage" \ | |
--name=runner.unit-test-branch-coverage \ | |
--user-data="${REPORTS_DIR}/coverage/summary.json" | |
integration-tests: | |
needs: [build-image, kosli-trail] | |
runs-on: ubuntu-latest | |
env: | |
IMAGE_NAME: ${{ needs.kosli-trail.outputs.image_name }} | |
KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.kosli_fingerprint }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Run integration tests with branch-coverage | |
run: | |
make integration_test | |
- name: Setup Kosli CLI | |
uses: kosli-dev/setup-cli-action@v2 | |
with: | |
version: ${{ vars.KOSLI_CLI_VERSION }} | |
- name: Attest results to Kosli | |
run: | | |
export REPORTS_DIR=./test/client/reports | |
kosli attest junit "${IMAGE_NAME}" \ | |
--name=runner.integration-test \ | |
--results-dir="${REPORTS_DIR}/junit" | |
kosli attest generic "${IMAGE_NAME}" \ | |
--attachments="${REPORTS_DIR}/coverage" \ | |
--name=runner.integration-test-branch-coverage \ | |
--user-data="${REPORTS_DIR}/coverage/summary.json" | |
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} \ | |
--file=Dockerfile \ | |
--sarif \ | |
--sarif-file-output="${SARIF_FILENAME}" \ | |
--policy-path=.snyk | |
set -e | |
mkdir "${KOSLI_ATTACHMENTS}" | |
cp .snyk "${KOSLI_ATTACHMENTS}" | |
kosli attest snyk "${IMAGE_NAME}" \ | |
--name=runner.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=runner.snyk-code-scan \ | |
--scan-results="${SARIF_FILENAME}" | |
sdlc-control-gate: | |
needs: [pull-request, lint, unit-tests, integration-tests, 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: | |
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: | |
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 }} |