diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6a0aacb4..fd8e72e8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,7 +20,7 @@ jobs: build-test-push: needs: [pre-build] - uses: cyber-dojo/reusable-actions-workflows/.github/workflows/kosli_build_test_push.yml@v0.0.6 + 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 }} @@ -38,7 +38,7 @@ jobs: deploy-staging: needs: [pre-build, build-test-push] - uses: cyber-dojo/reusable-actions-workflows/.github/workflows/kosli_deploy.yml@v0.0.6 + uses: cyber-dojo/reusable-actions-workflows/.github/workflows/kosli_deploy.yml@v0.0.11 permissions: id-token: write contents: write @@ -58,7 +58,7 @@ jobs: deploy-prod: needs: [pre-build, build-test-push] - uses: cyber-dojo/reusable-actions-workflows/.github/workflows/kosli_deploy.yml@v0.0.6 + uses: cyber-dojo/reusable-actions-workflows/.github/workflows/kosli_deploy.yml@v0.0.11 permissions: id-token: write contents: write diff --git a/.kosli.yml b/.kosli.yml new file mode 100644 index 00000000..da0c406a --- /dev/null +++ b/.kosli.yml @@ -0,0 +1,10 @@ +version: 1 + +trail: + artifacts: + - name: runner + attestations: + - name: branch-coverage + type: generic + - name: snyk-scan + type: snyk diff --git a/README.md b/README.md index 170cdc29..05a7ea7d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,8 @@ - A [docker-containerized](https://registry.hub.docker.com/r/cyberdojo/runner) micro-service for [https://cyber-dojo.org](http://cyber-dojo.org). - An http service (rack based) for running `cyber-dojo.sh` inside a docker container for at most 20 seconds and returning `[stdout,stderr,status,timed_out,colour]` -- A [Kosli](https://www.kosli.com/) showcase for a [CI flow](https://app.kosli.com/cyber-dojo/flows/runner/artifacts/) and an [aws production environment](https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/) +- A [Kosli](https://www.kosli.com/) showcase for a [CI flow](https://app.kosli.com/cyber-dojo/flows/runner-ci/trails/) + deploying, with Continuous Compliance, to [staging](https://app.kosli.com/cyber-dojo/environments/aws-beta/snapshots/) and [production](https://app.kosli.com/cyber-dojo/environments/aws-prod/snapshots/) AWS environments. *** diff --git a/build_test_publish.sh b/build_test_publish.sh index ca22a30f..e030a6db 100755 --- a/build_test_publish.sh +++ b/build_test_publish.sh @@ -26,7 +26,7 @@ exit_non_zero_unless_installed docker exit_non_zero_unless_installed docker-compose exit_non_zero_unless_installed jq remove_old_images -on_ci_kosli_create_flow +on_ci_kosli_begin_trail build_tagged_images "$@" exit_zero_if_build_only "$@" remove_zombie_containers @@ -36,10 +36,10 @@ create_test_data_manifests_file server_up_healthy_and_clean client_up_healthy_and_clean "$@" on_ci_publish_tagged_images -on_ci_kosli_report_artifact +on_ci_kosli_attest_artifact test_in_containers "$@" -on_ci_kosli_report_coverage_evidence -on_ci_kosli_report_snyk_scan_evidence +on_ci_kosli_attest_coverage_evidence +on_ci_kosli_attest_snyk_scan_evidence containers_down # Return non-zero for non-compliant artifact diff --git a/sh/kosli.sh b/sh/kosli.sh index b668134a..d7b50f93 100755 --- a/sh/kosli.sh +++ b/sh/kosli.sh @@ -1,7 +1,9 @@ #!/usr/bin/env bash set -Eeu -export KOSLI_FLOW=runner +export KOSLI_ORG=cyber-dojo +export KOSLI_FLOW=runner-ci +export KOSLI_TRAIL="${GITHUB_SHA}" # KOSLI_ORG is set in CI # KOSLI_API_TOKEN is set in CI @@ -11,7 +13,7 @@ export KOSLI_FLOW=runner # SNYK_TOKEN is set in CI # - - - - - - - - - - - - - - - - - - - -kosli_create_flow() +kosli_begin_trail() { local -r hostname="${1}" local -r api_token="${2}" @@ -20,53 +22,59 @@ kosli_create_flow() --description="Test runner" \ --host="${hostname}" \ --api-token="${api_token}" \ - --template artifact,branch-coverage,snyk-scan \ + --template-file="$(repo_root)/.kosli.yml" \ --visibility=public + + kosli begin trail "${KOSLI_TRAIL}" \ + --host="${hostname}" \ + --api-token="${api_token}" } # - - - - - - - - - - - - - - - - - - - -kosli_report_artifact() +kosli_attest_artifact() { local -r hostname="${1}" local -r api_token="${2}" - pushd "$(root_dir)" > /dev/null + pushd "$(repo_root)" > /dev/null - kosli report artifact "$(artifact_name)" \ + kosli attest artifact "$(artifact_name)" \ --artifact-type=docker \ --host="${hostname}" \ - --api-token="${api_token}" + --api-token="${api_token}" \ + --name=exercises-start-points \ + --name=runner popd > /dev/null } # - - - - - - - - - - - - - - - - - - - -kosli_report_coverage_evidence() +kosli_attest_coverage_evidence() { local -r hostname="${1}" local -r api_token="${2}" - kosli report evidence artifact generic $(artifact_name) \ + kosli attest generic $(artifact_name) \ --artifact-type=docker \ --description="server & client branch-coverage reports" \ - --name=branch-coverage \ + --name=runner.branch-coverage \ --host="${hostname}" \ --api-token="${api_token}" \ --user-data="$(evidence_json_path)" } # - - - - - - - - - - - - - - - - - - - -kosli_report_snyk_evidence() +kosli_attest_snyk_evidence() { local -r hostname="${1}" local -r api_token="${2}" - kosli report evidence artifact snyk "$(artifact_name)" \ + kosli attest snyk "$(artifact_name)" \ --artifact-type=docker \ --host="${hostname}" \ --api-token="${api_token}" \ - --name=snyk-scan \ - --scan-results="$(root_dir)/snyk.json" + --name=runner.snyk-scan \ + --scan-results="$(repo_root)/snyk.json" } # - - - - - - - - - - - - - - - - - - - @@ -82,64 +90,45 @@ kosli_assert_artifact() } # - - - - - - - - - - - - - - - - - - - -kosli_expect_deployment() -{ - local -r environment="${1}" - local -r hostname="${2}" - local -r api_token="${3}" - - # In .github/workflows/main.yml deployment is its own job - # and the image must be present to get its sha256 fingerprint. - docker pull "$(artifact_name)" - - kosli expect deployment "$(artifact_name)" \ - --artifact-type=docker \ - --description="Deployed to ${environment} in Github Actions pipeline" \ - --environment="${environment}" \ - --host="${hostname}" \ - --api-token="${api_token}" -} - -# - - - - - - - - - - - - - - - - - - - -on_ci_kosli_create_flow() +on_ci_kosli_begin_trail() { if on_ci; then - kosli_create_flow "${KOSLI_HOST_STAGING}" "${KOSLI_API_TOKEN_STAGING}" - kosli_create_flow "${KOSLI_HOST_PRODUCTION}" "${KOSLI_API_TOKEN}" + kosli_begin_trail "${KOSLI_HOST_STAGING}" "${KOSLI_API_TOKEN_STAGING}" + kosli_begin_trail "${KOSLI_HOST_PRODUCTION}" "${KOSLI_API_TOKEN}" fi } # - - - - - - - - - - - - - - - - - - - -on_ci_kosli_report_artifact() +on_ci_kosli_attest_artifact() { if on_ci; then - kosli_report_artifact "${KOSLI_HOST_STAGING}" "${KOSLI_API_TOKEN_STAGING}" - kosli_report_artifact "${KOSLI_HOST_PRODUCTION}" "${KOSLI_API_TOKEN}" + kosli_attest_artifact "${KOSLI_HOST_STAGING}" "${KOSLI_API_TOKEN_STAGING}" + kosli_attest_artifact "${KOSLI_HOST_PRODUCTION}" "${KOSLI_API_TOKEN}" fi } # - - - - - - - - - - - - - - - - - - - -on_ci_kosli_report_coverage_evidence() +on_ci_kosli_attest_coverage_evidence() { if on_ci; then write_evidence_json - kosli_report_coverage_evidence "${KOSLI_HOST_STAGING}" "${KOSLI_API_TOKEN_STAGING}" - kosli_report_coverage_evidence "${KOSLI_HOST_PRODUCTION}" "${KOSLI_API_TOKEN}" + kosli_attest_coverage_evidence "${KOSLI_HOST_STAGING}" "${KOSLI_API_TOKEN_STAGING}" + kosli_attest_coverage_evidence "${KOSLI_HOST_PRODUCTION}" "${KOSLI_API_TOKEN}" fi } # - - - - - - - - - - - - - - - - - - - -on_ci_kosli_report_snyk_scan_evidence() +on_ci_kosli_attest_snyk_scan_evidence() { if on_ci; then set +e snyk container test "$(artifact_name)" \ - --json-file-output="$(root_dir)/snyk.json" \ - --policy-path="$(root_dir)/.snyk" + --json-file-output="$(repo_root)/snyk.json" \ + --policy-path="$(repo_root)/.snyk" set -e - kosli_report_snyk_evidence "${KOSLI_HOST_STAGING}" "${KOSLI_API_TOKEN_STAGING}" - kosli_report_snyk_evidence "${KOSLI_HOST_PRODUCTION}" "${KOSLI_API_TOKEN}" + kosli_attest_snyk_evidence "${KOSLI_HOST_STAGING}" "${KOSLI_API_TOKEN_STAGING}" + kosli_attest_snyk_evidence "${KOSLI_HOST_PRODUCTION}" "${KOSLI_API_TOKEN}" fi } @@ -155,7 +144,7 @@ on_ci_kosli_assert_artifact() # - - - - - - - - - - - - - - - - - - - artifact_name() { - source "$(root_dir)/sh/echo_versioner_env_vars.sh" + source "$(repo_root)/sh/echo_versioner_env_vars.sh" export $(echo_versioner_env_vars) echo "${CYBER_DOJO_RUNNER_IMAGE}:${CYBER_DOJO_RUNNER_TAG}" } @@ -165,9 +154,9 @@ write_evidence_json() { { echo '{ "server": ' - cat "$(root_dir)/test/server/reports/coverage.json" + cat "$(repo_root)/test/server/reports/coverage.json" echo ', "client": ' - cat "$(root_dir)/test/client/reports/coverage.json" + cat "$(repo_root)/test/client/reports/coverage.json" echo '}' } > "$(evidence_json_path)" } @@ -175,7 +164,7 @@ write_evidence_json() # - - - - - - - - - - - - - - - - - - - evidence_json_path() { - echo "$(root_dir)/test/evidence.json" + echo "$(repo_root)/test/evidence.json" } # - - - - - - - - - - - - - - - - - - - - - - - - @@ -185,9 +174,9 @@ on_ci() } # - - - - - - - - - - - - - - - - - - - - - - - - -root_dir() +repo_root() { git rev-parse --show-toplevel } -export -f root_dir +export -f repo_root