Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions .github/workflows/get-repo-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
name: Get Repo Config and Image
on:
workflow_call:
inputs:
registry:
required: false
type: string
default: ghcr.io
namespace:
required: false
type: string
default: nhsdigital/eps-devcontainers
owner:
required: false
type: string
default: NHSDigital
verify_published_from_main_image:
required: false
type: boolean
default: true
predicate_type:
required: false
type: string
default: https://slsa.dev/provenance/v1
outputs:
tag_format:
description: The tag format to be used for releases, as defined in .github/config/settings.yml
value: ${{ jobs.get_config_values.outputs.tag_format }}
devcontainer_image:
description: The devcontainer image name as defined in .devcontainer/devcontainer.json
value: ${{ jobs.get_config_values.outputs.devcontainer_image }}
devcontainer_version:
description: The devcontainer image version as defined in .devcontainer/devcontainer.json
value: ${{ jobs.get_config_values.outputs.devcontainer_version }}
pinned_image:
description: Fully-qualified digest-pinned image reference
value: ${{ jobs.verify_attestation.outputs.pinned_image }}
resolved_digest:
description: Resolved digest for the supplied image reference
value: ${{ jobs.verify_attestation.outputs.resolved_digest }}

jobs:
get_config_values:
runs-on: ubuntu-22.04
outputs:
tag_format: ${{ steps.load-config.outputs.TAG_FORMAT }}
devcontainer_version: ${{ steps.load-config.outputs.DEVCONTAINER_VERSION }}
devcontainer_image: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE }}
runtime_docker_image: ${{ steps.load-config.outputs.RUNTIME_DOCKER_IMAGE }}
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
ref: ${{ env.BRANCH_NAME }}
fetch-depth: 0

- name: Load config value
id: load-config
run: |
TAG_FORMAT=$(yq '.TAG_FORMAT' .github/config/settings.yml)
DEVCONTAINER_IMAGE=$(jq -r '.build.args.IMAGE_NAME' .devcontainer/devcontainer.json)
DEVCONTAINER_VERSION=$(jq -r '.build.args.IMAGE_VERSION' .devcontainer/devcontainer.json)
RUNTIME_DOCKER_IMAGE="${DEVCONTAINER_IMAGE}:githubactions-${DEVCONTAINER_VERSION}"
{
echo "TAG_FORMAT=$TAG_FORMAT"
echo "DEVCONTAINER_IMAGE=$DEVCONTAINER_IMAGE"
echo "DEVCONTAINER_VERSION=$DEVCONTAINER_VERSION"
echo "RUNTIME_DOCKER_IMAGE=$RUNTIME_DOCKER_IMAGE"
} >> "$GITHUB_OUTPUT"

verify_attestation:
runs-on: ubuntu-22.04
needs: get_config_values
permissions:
contents: read
packages: read
attestations: read
outputs:
pinned_image: ${{ steps.resolve.outputs.pinned_image }}
resolved_digest: ${{ steps.resolve.outputs.resolved_digest }}
steps:
- name: Login to github container registry
if: startsWith(inputs.registry, 'ghcr.io')
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Resolve digest
id: resolve
shell: bash
env:
RUNTIME_DOCKER_IMAGE: ${{ needs.get_config_values.outputs.runtime_docker_image }}
REGISTRY: ${{ inputs.registry }}
NAMESPACE: ${{ inputs.namespace }}
run: |
set -euo pipefail

if [[ "$RUNTIME_DOCKER_IMAGE" == *"/"* ]]; then
IMAGE_REF="$RUNTIME_DOCKER_IMAGE"
else
IMAGE_REF="${REGISTRY}/${NAMESPACE}/${RUNTIME_DOCKER_IMAGE}"
fi

if [[ "$IMAGE_REF" == *@sha256:* ]]; then
IMAGE_BASE="${IMAGE_REF%@*}"
RESOLVED_DIGEST="${IMAGE_REF#*@}"
else
RESOLVED_DIGEST="$(docker buildx imagetools inspect "$IMAGE_REF" | awk '/^Digest:/ {print $2; exit}')"
IMAGE_BASE="${IMAGE_REF%:*}"
fi

if [[ -z "$RESOLVED_DIGEST" ]]; then
echo "Could not resolve digest for image: $IMAGE_REF" >&2
exit 1
fi

PINNED_IMAGE="${IMAGE_BASE}@${RESOLVED_DIGEST}"
echo "resolved_digest=${RESOLVED_DIGEST}" >> "$GITHUB_OUTPUT"
echo "pinned_image=${PINNED_IMAGE}" >> "$GITHUB_OUTPUT"
echo "Resolved image reference: ${IMAGE_REF}"
echo "Resolved digest: ${RESOLVED_DIGEST}"
echo "Resolved image reference: ${PINNED_IMAGE}"

- name: Verify attestation
shell: bash
env:
GH_TOKEN: ${{ github.token }}
OWNER: ${{ inputs.owner }}
VERIFY_PUBLISHED_FROM_MAIN_IMAGE: ${{ inputs.verify_published_from_main_image }}
PREDICATE_TYPE: ${{ inputs.predicate_type }}
PINNED_IMAGE: ${{ steps.resolve.outputs.pinned_image }}
run: |
set -euo pipefail

args=("oci://${PINNED_IMAGE}" "--owner" "$OWNER" "--predicate-type" "$PREDICATE_TYPE")

if [[ "$VERIFY_PUBLISHED_FROM_MAIN_IMAGE" == "true" ]]; then
args+=("--source-ref" "refs/heads/main")
fi


GH_FORCE_TTY=120 gh attestation verify "${args[@]}" 2>&1
echo "Verified attestation for ${PINNED_IMAGE}"
29 changes: 5 additions & 24 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: pr
name: Pull Request

on:
pull_request:
Expand All @@ -17,43 +17,24 @@ jobs:
pr_title_format_check:
uses: ./.github/workflows/pr_title_check.yml
get_config_values:
runs-on: ubuntu-22.04
outputs:
tag_format: ${{ steps.load-config.outputs.TAG_FORMAT }}
devcontainer_version: ${{ steps.load-config.outputs.DEVCONTAINER_VERSION }}
devcontainer_image: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE }}
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

- name: Load config value
id: load-config
run: |
TAG_FORMAT=$(yq '.TAG_FORMAT' .github/config/settings.yml)
DEVCONTAINER_IMAGE=$(jq -r '.build.args.IMAGE_NAME' .devcontainer/devcontainer.json)
DEVCONTAINER_VERSION=$(jq -r '.build.args.IMAGE_VERSION' .devcontainer/devcontainer.json)
{
echo "TAG_FORMAT=$TAG_FORMAT"
echo "DEVCONTAINER_IMAGE=$DEVCONTAINER_IMAGE"
echo "DEVCONTAINER_VERSION=$DEVCONTAINER_VERSION"
} >> "$GITHUB_OUTPUT"
uses: ./.github/workflows/get-repo-config.yml
quality_checks:
uses: ./.github/workflows/quality-checks-devcontainer.yml
needs: [get_config_values]
with:
runtime_docker_image: "${{ needs.get_config_values.outputs.devcontainer_image }}:githubactions-${{ needs.get_config_values.outputs.devcontainer_version }}"
pinned_image: ${{ needs.get_config_values.outputs.pinned_image }}
secrets:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
tag_release:
needs: [quality_checks, get_config_values]
needs: get_config_values
uses: ./.github/workflows/tag-release-devcontainer.yml
permissions:
contents: read
packages: read
attestations: read
with:
dry_run: true
runtime_docker_image: "${{ needs.get_config_values.outputs.devcontainer_image }}:githubactions-${{ needs.get_config_values.outputs.devcontainer_version }}"
pinned_image: ${{ needs.get_config_values.outputs.pinned_image }}
branch_name: ${{ github.event.pull_request.head.ref }}
tag_format: ${{ needs.get_config_values.outputs.tag_format }}
verify_published_from_main_image: false
Expand Down
20 changes: 6 additions & 14 deletions .github/workflows/quality-checks-devcontainer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,15 @@ on:
description: comma separated list of docker image references to scan when docker scanning is enabled.
default: ""
required: false
runtime_docker_image:
pinned_image:
type: string
required: true

jobs:
verify_attestation:
uses: ./.github/workflows/verify-attestation.yml
with:
runtime_docker_image: "${{ inputs.runtime_docker_image }}"
verify_published_from_main_image: false
quality_checks:
runs-on: ubuntu-22.04
needs: verify_attestation
container:
image: ${{ needs.verify_attestation.outputs.pinned_image }}
image: ${{ inputs.pinned_image }}
options: --user 1001:1001 --group-add 128
defaults:
run:
Expand Down Expand Up @@ -213,9 +207,8 @@ jobs:

get_docker_images_to_scan:
runs-on: ubuntu-22.04
needs: verify_attestation
container:
image: ${{ needs.verify_attestation.outputs.pinned_image }}
image: ${{ inputs.pinned_image }}
options: --user 1001:1001 --group-add 128
defaults:
run:
Expand Down Expand Up @@ -283,9 +276,9 @@ jobs:

docker_vulnerability_scan:
runs-on: ubuntu-22.04
needs: [get_docker_images_to_scan, verify_attestation]
needs: get_docker_images_to_scan
container:
image: ${{ needs.verify_attestation.outputs.pinned_image }}
image: ${{ inputs.pinned_image }}
options: --user 1001:1001 --group-add 128
defaults:
run:
Expand Down Expand Up @@ -326,9 +319,8 @@ jobs:

IaC-validation:
runs-on: ubuntu-22.04
needs: verify_attestation
container:
image: ${{ needs.verify_attestation.outputs.pinned_image }}
image: ${{ inputs.pinned_image }}
options: --user 1001:1001 --group-add 128
defaults:
run:
Expand Down
25 changes: 3 additions & 22 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,20 @@ env:

jobs:
get_config_values:
runs-on: ubuntu-22.04
outputs:
tag_format: ${{ steps.load-config.outputs.TAG_FORMAT }}
devcontainer_version: ${{ steps.load-config.outputs.DEVCONTAINER_VERSION }}
devcontainer_image: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE }}
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

- name: Load config value
id: load-config
run: |
TAG_FORMAT=$(yq '.TAG_FORMAT' .github/config/settings.yml)
DEVCONTAINER_IMAGE=$(jq -r '.build.args.IMAGE_NAME' .devcontainer/devcontainer.json)
DEVCONTAINER_VERSION=$(jq -r '.build.args.IMAGE_VERSION' .devcontainer/devcontainer.json)
{
echo "TAG_FORMAT=$TAG_FORMAT"
echo "DEVCONTAINER_IMAGE=$DEVCONTAINER_IMAGE"
echo "DEVCONTAINER_VERSION=$DEVCONTAINER_VERSION"
} >> "$GITHUB_OUTPUT"
uses: ./.github/workflows/get-repo-config.yml
quality_checks:
needs: [get_config_values]
uses: ./.github/workflows/quality-checks-devcontainer.yml
with:
runtime_docker_image: "${{ needs.get_config_values.outputs.devcontainer_image }}:githubactions-${{ needs.get_config_values.outputs.devcontainer_version }}"
pinned_image: ${{ needs.get_config_values.outputs.pinned_image }}
secrets:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
tag_release:
needs: [quality_checks, get_config_values]
uses: ./.github/workflows/tag-release-devcontainer.yml
with:
dry_run: false
runtime_docker_image: "${{ needs.get_config_values.outputs.devcontainer_image }}:githubactions-${{ needs.get_config_values.outputs.devcontainer_version }}"
pinned_image: ${{ needs.get_config_values.outputs.pinned_image }}
branch_name: main
tag_format: ${{ needs.get_config_values.outputs.tag_format }}
verify_published_from_main_image: true
Expand Down
10 changes: 2 additions & 8 deletions .github/workflows/tag-release-devcontainer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
description: "The branch name to base the release on"
required: true
type: string
runtime_docker_image:
pinned_image:
type: string
required: true
publish_packages:
Expand Down Expand Up @@ -62,16 +62,10 @@ on:
required: false
description: "NPM token to publish packages"
jobs:
verify_attestation:
uses: ./.github/workflows/verify-attestation.yml
with:
runtime_docker_image: "${{ inputs.runtime_docker_image }}"
verify_published_from_main_image: ${{ inputs.verify_published_from_main_image }}
tag_release:
runs-on: ubuntu-22.04
needs: verify_attestation
container:
image: ${{ needs.verify_attestation.outputs.pinned_image }}
image: ${{ inputs.pinned_image }}
options: --user 1001:1001 --group-add 128
defaults:
run:
Expand Down
Loading