Skip to content

Commit

Permalink
ci: add main ci jobs
Browse files Browse the repository at this point in the history
  • Loading branch information
xopham committed Feb 1, 2024
1 parent 0acb9d1 commit a64227c
Show file tree
Hide file tree
Showing 37 changed files with 1,791 additions and 29 deletions.
173 changes: 173 additions & 0 deletions .github/actions/build/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
name: build
description: 'Build connaisseur image'
inputs:
image_registry:
description: 'Image registry to be used'
required: true
image_repo:
description: 'Image repository to be used'
required: true
image_tag:
description: 'Image tag to be used'
required: true
ref_tags:
description: 'Reference tags to be used'
required: true
image_labels:
description: 'Image labels to be used'
required: true
repo_owner:
description: 'Name of repository owner, e.g. "github.repository_owner" for ghcr.io'
required: true
repo_token:
description: 'Access token for repository owner, e.g. "secrets.GITHUB_TOKEN" for ghcr.io'
required: true
cosign_version:
description: 'Cosign version to be used'
required: true
cosign_private_key:
description: 'Cosign private key'
required: true
cosign_password:
description: 'Cosign private key password'
required: true
outputs:
cosign_public_key:
description: 'Cosign public key'
value: ${{ steps.verify.outputs.public_key }}
runs:
using: "composite"
steps:
- name: Install Cosign
uses: sigstore/cosign-installer@11086d25041f77fe8fe7b9ea4e48e3b9192b8f19 # v3.1.2 (probably)
- name: Set up Docker buildx
uses: docker/setup-buildx-action@f03ac48505955848960e80bbb68046aa35c7b9e7 # v2.4.1
- name: Login with registry
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2.1.0
with:
registry: ${{ inputs.image_registry }}
username: ${{ inputs.repo_owner }}
password: ${{ inputs.repo_token }}
- name: Generate tags
id: tags
run: |
echo "${{ inputs.ref_tags }}"
export PREFIX="${{ inputs.image_registry }}/${{ inputs.image_repo }}:"
TAGS="${PREFIX}${{ inputs.image_tag }},$(echo ${{ inputs.ref_tags }} | tr ' ' '\n' | awk '{print "${PREFIX}"$1}' | envsubst | tr '\n' ',')"
echo tags=${TAGS} >> ${GITHUB_OUTPUT}
shell: bash
- name: Build and push image
id: build
uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 # v4.0.0
with:
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
file: build/Dockerfile
labels: ${{ inputs.image_labels }}
tags: ${{ steps.tags.outputs.tags }}
provenance: true
sbom: true
- name: Create SBOM
uses: anchore/sbom-action@07978da4bdb4faa726e52dfc6b1bed63d4b56479 # v0.13.3
with:
image: ${{ inputs.image_registry }}/${{ inputs.image_repo }}@${{ steps.build.outputs.digest }}
format: cyclonedx-json
artifact-name: sbom.cdx
output-file: sbom.cdx
- name: Sign image
id: sign
run: |
cosign sign --key env://COSIGN_PRIVATE_KEY -a tag=${{ inputs.image_tag }} -y ${TAGS}
cosign attach sbom --sbom sbom.cdx --type cyclonedx ${TAGS}
cosign sign --key env://COSIGN_PRIVATE_KEY --attachment sbom -y ${TAGS}
env:
TAGS: ${{ inputs.image_registry }}/${{ inputs.image_repo }}@${{ steps.build.outputs.digest }}
COSIGN_PRIVATE_KEY: ${{ inputs.cosign_private_key }}
COSIGN_PASSWORD: ${{ inputs.cosign_password }}
shell: bash
- name: Verify build data
id: verify
run: |
mkdir ci
cosign public-key --key env://COSIGN_PRIVATE_KEY > ci/cosign.pub
PUBLIC_KEY="$(cat ci/cosign.pub)"
cosign tree ${TAGS}
PUBLIC_KEY=${PUBLIC_KEY} cosign verify --key env://PUBLIC_KEY ${TAGS}
PUBLIC_KEY=${PUBLIC_KEY} cosign verify --key env://PUBLIC_KEY --attachment sbom ${TAGS}
SIGNATURE=$(cosign triangulate ${TAGS})
PUBLIC_KEY="${PUBLIC_KEY//$'\n'/'<br>'}"
SBOM="${SIGNATURE::-4}.sbom"
echo public_key="${PUBLIC_KEY}" >> ${GITHUB_OUTPUT}
echo signature=${SIGNATURE} >> ${GITHUB_OUTPUT}
echo sbom=${SBOM} >> ${GITHUB_OUTPUT}
env:
TAGS: ${{ inputs.image_registry }}/${{ inputs.image_repo }}@${{ steps.build.outputs.digest }}
COSIGN_PRIVATE_KEY: ${{ inputs.cosign_private_key }}
COSIGN_PASSWORD: ${{ inputs.cosign_password }}
shell: bash
- name: Upload public key
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
with:
name: cosign.pub
path: ci/cosign.pub
- name: Show build and signature information
run: |
CONFIGURE="yq '. *+ load(\"tests/integration/var-img.yaml\")' tests/integration/ghcr-values.yaml > ghcr.yaml &&\n\t IMAGE=\"${{ inputs.image_registry }}/${{ inputs.image_repo }}\" TAG=\"${{ inputs.image_tag }}\" IMAGEPULLSECRET=\"<ImagePullSecret name>\" envsubst < ghcr.yaml > update &&\n\t yq '. *+ load(\"update\")' -i charts/connaisseur/values.yaml &&\n\t rm ghcr.yaml update"
CONFIGURE=$(printf -- "${CONFIGURE}")
PUBLIC_KEY="${{ steps.verify.outputs.public_key }}"
PUBLIC_KEY="$(printf -- "${PUBLIC_KEY//'<br>'/'\n'}")"
HELM_PATCH="yq e '.kubernetes.deployment.image.repository = \"${{ inputs.image_registry }}/${{ inputs.image_repo }}\"' -i charts/connaisseur/values.yaml\nyq e '.kubernetes.deployment.image.tag = \"${{ inputs.image_tag }}\"' -i charts/connaisseur/values.yaml"
HELM_PATCH=$(printf -- "${HELM_PATCH}")
echo "# :building_construction: Build Information" >> ${GITHUB_STEP_SUMMARY}
echo "<table>" >> ${GITHUB_STEP_SUMMARY}
echo "<tr><th>Build artifacts</th><th>Value</th></tr>" >> ${GITHUB_STEP_SUMMARY}
echo "<tr><td>Registry</td><td><code>${{ inputs.image_registry }}</code></td></tr>" >> ${GITHUB_STEP_SUMMARY}
echo "<tr><td>Repository</td><td><code>${{ inputs.image_repo }}</code></td></tr>" >> ${GITHUB_STEP_SUMMARY}
echo "<tr><td>Tags</td><td><code>${{ inputs.image_tag }}</code>, <code>${{ inputs.ref_tags }}</code></td></tr>" >> ${GITHUB_STEP_SUMMARY}
echo "<tr><td>Workflow image</td><td><code>${{ inputs.image_registry }}/${{ inputs.image_repo }}:${{ inputs.image_tag }}</code></td></tr>" >> ${GITHUB_STEP_SUMMARY}
echo "<tr><td>All reference tags</td><td><code>$(echo ${{ steps.tags.outputs.tags }} | tr ',' '\n')</code></td></tr>" >> ${GITHUB_STEP_SUMMARY}
echo "<tr><td>Digest</td><td><code>${{ steps.build.outputs.digest }}</code></td></tr>" >> ${GITHUB_STEP_SUMMARY}
echo "<tr><td>Signature</td><td><code>${{ steps.verify.outputs.signature }}</code></td></tr>" >> ${GITHUB_STEP_SUMMARY}
echo "<tr><td>Public key</td><td><code>${PUBLIC_KEY}</code></td></tr>" >> ${GITHUB_STEP_SUMMARY}
echo "<tr><td>SBOM (cyclonedx-json)</td><td><code>${{ steps.verify.outputs.sbom }}</code></td></tr>" >> ${GITHUB_STEP_SUMMARY}
echo "</table>" >> ${GITHUB_STEP_SUMMARY}
echo "" >> ${GITHUB_STEP_SUMMARY}
echo "<details><summary>:bookmark_tabs: Metadata</summary>" >> ${GITHUB_STEP_SUMMARY}
echo "<pre><code>${{ steps.build.outputs.metadata }}</code></pre>" >> ${GITHUB_STEP_SUMMARY}
echo "</details>" >> ${GITHUB_STEP_SUMMARY}
echo "" >> ${GITHUB_STEP_SUMMARY}
echo "<details><summary>:hammer_and_wrench: Use Build Artifacts</summary>" >> ${GITHUB_STEP_SUMMARY}
echo "(needs <a href='https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry'>docker login via PAT</a> with package:read permission)" >> ${GITHUB_STEP_SUMMARY}
echo "<ul>" >> ${GITHUB_STEP_SUMMARY}
echo "<li><b>Workflow image reference</b> by tag: <pre><code>${{ inputs.image_registry }}/${{ inputs.image_repo }}:${{ inputs.image_tag }}</code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "<li><b>Main image reference</b> by tag: <pre><code>${{ inputs.image_registry }}/${{ inputs.image_repo }}:$(echo ${{ inputs.ref_tags }} | tr ' ' '\n' | head -n1)</code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "<li><b>Image reference</b> by digest: <pre><code>${{ inputs.image_registry }}/${{ inputs.image_repo }}@${{ steps.build.outputs.digest }}</code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "<li><b>Cosign signature</b>: <pre><code>${{ steps.verify.outputs.signature }}</code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "<li><b>Syft SBOM (cyclonedx-json)</b>: <pre><code>${{ steps.verify.outputs.sbom }}</code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "<li>Pull via <b>Docker</b>: <pre lang="bash"><code>docker pull ${{ inputs.image_registry }}/${{ inputs.image_repo }}:${{ inputs.image_tag }}</code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "<li>Use in <b>Helm chart</b> (needs <a href='https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/'>imagePullSecret via dockerconfigjson<a> of PAT with package:read permission): <pre lang="bash"><code>${HELM_PATCH}</code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "<li>Configure <b>Helm chart</b> for successful validation build image (RUN ONLY ONCE, insert name of <code>imagePullSecret</code> in connaisseur namespace): <pre lang="bash"><code>${CONFIGURE}</code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "</ul>" >> ${GITHUB_STEP_SUMMARY}
echo "</details>" >> ${GITHUB_STEP_SUMMARY}
echo "" >> ${GITHUB_STEP_SUMMARY}
echo "<details><summary>:mag: Verify Build</summary>" >> ${GITHUB_STEP_SUMMARY}
echo "(needs <a href='https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry'>Docker login via PAT</a> with package:read permission)" >> ${GITHUB_STEP_SUMMARY}
echo "<ul>" >> ${GITHUB_STEP_SUMMARY}
echo "<li>Show <b>BuildKit image details</b>: <pre><code>docker buildx imagetools inspect ${{ inputs.image_registry }}/${{ inputs.image_repo }}:${{ inputs.image_tag }}</code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "<li>Extract <b>BuildKit SBOM</b> (can be consumed by e.g. <a href='https://github.com/anchore/syft'>syft</a> or <a href='https://github.com/anchore/grype'>grype</a>): <pre><code>docker buildx imagetools inspect ${{ inputs.image_registry }}/${{ inputs.image_repo }}:${{ inputs.image_tag }} --format \"{{ json .SBOM.SPDX }}\"</code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "<li>Extract <b>BuildKit provenance (<a href='https://slsa.dev/provenance/v0.2'>SLSA</a>)</b> data: <pre><code>docker buildx imagetools inspect ${{ inputs.image_registry }}/${{ inputs.image_repo }}:${{ inputs.image_tag }} --format \"{{ json .Provenance.SLSA }}\"</code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "<li><b>Cosign public key</b>: <pre><code>${PUBLIC_KEY}</code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "<li>Store <b>Cosign public key</b>: <pre lang="bash"><code>echo \"${PUBLIC_KEY}\" > cosign.pub </code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "<li>Verify <b>Cosign signature</b> using <code>cosign.pub</code> file: <pre lang="bash"><code>cosign verify --key cosign.pub ${{ inputs.image_registry }}/${{ inputs.image_repo }}:${{ inputs.image_tag }} </code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "<li>Verify <b>Cosign signature</b> : <pre lang="bash"><code>COSIGN_PUBLIC_KEY='${PUBLIC_KEY}' cosign verify --key env://COSIGN_PUBLIC_KEY ${{ inputs.image_registry }}/${{ inputs.image_repo }}:${{ inputs.image_tag }} </code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "<li>Display all <b>Cosign supply chain security artifacts</b>: <pre lang="bash"><code>cosign tree ${{ inputs.image_registry }}/${{ inputs.image_repo }}:${{ inputs.image_tag }} </code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "<li>Download <b>Cosign-attached SBOM</b> (syft-generated cyclonedx-json): <pre lang="bash"><code>
COSIGN_PUBLIC_KEY='${PUBLIC_KEY}' cosign verify --key env://COSIGN_PUBLIC_KEY --attachment sbom ${{ inputs.image_registry }}/${{ inputs.image_repo }}:${{ inputs.image_tag }} && # verify signature before download
cosign download sbom ${{ inputs.image_registry }}/${{ inputs.image_repo }}:${{ inputs.image_tag }} > sbom.cdx # perform actual download
</code></pre></li>" >> ${GITHUB_STEP_SUMMARY}
echo "</ul>" >> ${GITHUB_STEP_SUMMARY}
echo "</details>" >> ${GITHUB_STEP_SUMMARY}
echo "" >> ${GITHUB_STEP_SUMMARY}
echo "Let's start testing :rocket:" >> ${GITHUB_STEP_SUMMARY}
shell: bash
Loading

0 comments on commit a64227c

Please sign in to comment.