Add Attestations #414
Workflow file for this run
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: Release | ||
on: | ||
workflow_call: | ||
permissions: | ||
contents: read | ||
jobs: | ||
pypi-publish: | ||
name: upload release to PyPI | ||
if: startsWith(github.ref, 'refs/tags/v') | ||
runs-on: ubuntu-latest | ||
environment: release | ||
permissions: | ||
id-token: write | ||
attestations: write | ||
steps: | ||
- name: Download artifact | ||
uses: actions/download-artifact@v4 | ||
with: | ||
pattern: fasttrackml-wheels-* | ||
merge-multiple: true | ||
path: wheelhouse | ||
- name: Add attestations | ||
uses: actions/attest-build-provenance@v1 | ||
with: | ||
subject-path: wheelhouse/*.whl | ||
- name: Publish package distributions to PyPI | ||
uses: pypa/gh-action-pypi-publish@release/v1 | ||
with: | ||
packages-dir: wheelhouse | ||
github-release: | ||
name: Publish GitHub release | ||
if: startsWith(github.ref, 'refs/tags/v') | ||
runs-on: ubuntu-latest | ||
permissions: | ||
actions: write | ||
contents: write | ||
steps: | ||
- name: Download artifact | ||
uses: actions/download-artifact@v4 | ||
with: | ||
pattern: fasttrackml-archives-* | ||
merge-multiple: true | ||
path: dist | ||
- name: Create release | ||
uses: softprops/action-gh-release@v2 | ||
with: | ||
generate_release_notes: true | ||
files: dist/* | ||
prerelease: ${{ contains(github.ref, '-') }} | ||
- name: Trigger website update | ||
if: ${{ !contains(github.ref, '-') }} | ||
env: | ||
GH_TOKEN: ${{ github.token }} | ||
run: gh workflow run --repo ${{ github.repository }} website.yml | ||
docker-release: | ||
name: Publish container image to DockerHub | ||
if: startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main' | ||
runs-on: ubuntu-latest | ||
environment: release | ||
permissions: | ||
id-token: write | ||
attestations: write | ||
steps: | ||
# We need to checkout the repo in order to determine the latest tag. | ||
- name: Checkout | ||
if: startsWith(github.ref, 'refs/tags/v') | ||
uses: actions/checkout@v4 | ||
with: | ||
fetch-tags: 1 | ||
# The main branch is tagged as "main" and "edge". | ||
# Tags are named after the version, e.g. "v0.1.0" -> "0.1.0". | ||
# The latest non-prerelease version is also tagged as "latest". | ||
# This is achieved by sorting the tags by version number, then filtering | ||
# out prereleases and taking the last tag. | ||
- name: Compute tags | ||
id: tags | ||
run: | | ||
ref='${{ github.ref }}' | ||
case $ref in | ||
refs/heads/main) | ||
tags=("main" "edge") | ||
;; | ||
refs/tags/v*) | ||
tags=("${ref#refs/tags/v}") | ||
if [ "$(git -c 'versionsort.suffix=-' for-each-ref --sort=version:refname --format='%(refname)' 'refs/tags/v*' | grep -v -- - | tail -n1)" == "$ref" ]; then | ||
tags+=("latest") | ||
fi | ||
esac | ||
echo "ref=${ref#refs/*/}" >> $GITHUB_OUTPUT | ||
echo "tags=${tags[@]}" >> $GITHUB_OUTPUT | ||
- name: Download artifact | ||
uses: actions/download-artifact@v4 | ||
with: | ||
pattern: fasttrackml-oci-images-* | ||
merge-multiple: true | ||
- name: Login to Docker Hub | ||
uses: docker/login-action@v3 | ||
with: | ||
username: ${{ secrets.DOCKER_USERNAME }} | ||
password: ${{ secrets.DOCKER_PASSWORD }} | ||
- name: Push to Docker Hub | ||
run: | | ||
tags=(${{ steps.tags.outputs.tags }}) | ||
for image in fasttrackml-oci-*.tar | ||
do | ||
digest=$(tar -xOf $image index.json | jq -r '.manifests[0].digest') | ||
digests+=($digest) | ||
echo "::group::Pushing $image to ${{ vars.DOCKER_REPO }}@$digest" | ||
skopeo copy oci-archive:$image:${{ steps.tags.outputs.ref }} docker://${{ vars.DOCKER_REPO }}@$digest | ||
echo "::endgroup::" | ||
done | ||
echo "::group::Pushing merged manifest to ${{ vars.DOCKER_REPO }} for tags: ${tags[@]}" | ||
docker buildx imagetools create \ | ||
$(printf -- "--tag ${{ vars.DOCKER_REPO }}:%s " ${tags[@]}) \ | ||
$(printf "${{ vars.DOCKER_REPO }}@%s " ${digests[@]}) | ||
echo "::endgroup::" | ||
# Output digests as a JSON array for use in a matrix | ||
echo "::set-output name=digests::$(printf '%s\n' "${digests[@]}" | jq -R . | jq -s .)" | ||
outputs: | ||
digests: ${{ steps.set-matrix.outputs.matrix }} | ||
attest-docker-images: | ||
name: Publish Docker images attestations | ||
strategy: | ||
matrix: | ||
digest: ${{ fromJson(needs.docker-release.outputs.digests) }} | ||
steps: | ||
- name: Attest Each Docker Image | ||
uses: actions/attest-build-provenance@v2 | ||
with: | ||
subject-name: index.docker.io/${{ vars.DOCKER_REPO }} | ||
subject-digest: ${{ matrix.digest }} | ||
push-to-registry: true | ||
chart-release: | ||
name: Publish Helm chart | ||
if: startsWith(github.ref, 'refs/tags/v') | ||
uses: G-Research/charts/.github/workflows/invoke-push.yaml@master | ||
secrets: | ||
APP_ID: ${{ secrets.APP_ID }} | ||
APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }} |