mirror of
https://github.com/zama-ai/concrete.git
synced 2026-02-08 19:44:57 -05:00
656 lines
27 KiB
YAML
656 lines
27 KiB
YAML
name: concretefhe CI Pipeline
|
|
on:
|
|
pull_request:
|
|
push:
|
|
branches:
|
|
- main
|
|
tags:
|
|
- "v*"
|
|
|
|
# Allows you to run this workflow manually from the Actions tab
|
|
workflow_dispatch:
|
|
|
|
# Allows external webhook trigger
|
|
repository_dispatch:
|
|
types:
|
|
- rebuild-env-docker
|
|
|
|
schedule:
|
|
# * is a special character in YAML so you have to quote this string
|
|
# At 22:00 on Sunday
|
|
# Timezone is UTC, so Paris time is +2 during the summer and +1 during winter
|
|
- cron: '0 22 * * 0'
|
|
|
|
env:
|
|
FORCE_REBUILD_DOCKER: ${{ github.event_name == 'workflow_dispatch' || (github.event_name == 'repository_dispatch' && github.event.action == 'rebuild-env-docker') }}
|
|
ENV_DOCKERFILE: docker/Dockerfile.concretefhe-env
|
|
PREFLIGHT_IMAGE_BASE: ghcr.io/zama-ai/concretefhe-env:preflight
|
|
LATEST_IMAGE: ghcr.io/zama-ai/concretefhe-env:latest
|
|
BASE_IMAGE: ghcr.io/zama-ai/concretefhe-env
|
|
ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
IS_PR: ${{ github.event_name == 'pull_request' }}
|
|
|
|
jobs:
|
|
build-preflight-docker:
|
|
concurrency:
|
|
group: ${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
name: Build & Push the concretefhe-env preflight Docker Image
|
|
runs-on: ubuntu-20.04
|
|
outputs:
|
|
image: ${{ steps.set_image.outputs.image || env.LATEST_IMAGE }}
|
|
needs-push: ${{ env.BUILD_DOCKER }}
|
|
force-rebuild-docker: ${{ env.FORCE_REBUILD_DOCKER }}
|
|
report: ${{ steps.report.outputs.report || 'Did not run.' }}
|
|
|
|
steps:
|
|
- uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f
|
|
with:
|
|
fetch-depth: 0
|
|
- name: Get changed files
|
|
if: ${{ (github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/')) || github.event_name == 'pull_request' }}
|
|
id: files
|
|
run: |
|
|
CURRENT_SHA="${{ github.sha }}"
|
|
if [[ "${IS_PR}" == "true" ]]; then
|
|
BEFORE_SHA="${{ github.event.pull_request.base.sha }}"
|
|
else
|
|
BEFORE_SHA="$(./script/actions_utils/get_latest_run.sh \
|
|
--token ${{ secrets.BOT_TOKEN }} \
|
|
--org-repo ${{ github.repository }} \
|
|
--event-types 'push workflow_dispatch repository_dispatch')"
|
|
fi
|
|
ALL_CHANGED_FILES=$(git diff --name-only "${CURRENT_SHA}" "${BEFORE_SHA}")
|
|
|
|
echo "Before sha1 ${BEFORE_SHA}"
|
|
echo "Current sha1 ${CURRENT_SHA}"
|
|
|
|
echo "Changed files:"
|
|
echo "${ALL_CHANGED_FILES}"
|
|
|
|
echo "::set-output name=all::${ALL_CHANGED_FILES//$'\n'/ }"
|
|
|
|
- name: Should rebuild docker check
|
|
run: |
|
|
set +e
|
|
echo "${{ steps.files.outputs.all }}" | grep "${ENV_DOCKERFILE}"
|
|
DOCKERFILE_CHANGED=$?
|
|
if [[ "${DOCKERFILE_CHANGED}" == "0" || "${FORCE_REBUILD_DOCKER}" == "true" ]]; then
|
|
echo "Should rebuild docker image!"
|
|
echo "BUILD_DOCKER=true" >> "$GITHUB_ENV"
|
|
else
|
|
echo "Docker image up to date."
|
|
echo "BUILD_DOCKER=false" >> "$GITHUB_ENV"
|
|
fi
|
|
- name: Set prefligh Docker image
|
|
id: set_image
|
|
if: ${{ fromJSON(env.BUILD_DOCKER) }}
|
|
run: |
|
|
PREFLIGHT_IMAGE_TAG=$(echo ${{ github.ref }} | sed -e 's/\//-/g')
|
|
PREFLIGHT_IMAGE="${PREFLIGHT_IMAGE_BASE}-${PREFLIGHT_IMAGE_TAG}"
|
|
LABEL_SHA1=$(git rev-parse HEAD)
|
|
echo "::set-output name=image::${PREFLIGHT_IMAGE}"
|
|
echo "PREFLIGHT_IMAGE=${PREFLIGHT_IMAGE}" >> "$GITHUB_ENV"
|
|
echo "LABEL_SHA1=${LABEL_SHA1}" >> "$GITHUB_ENV"
|
|
- name: Set up Docker Buildx
|
|
if: ${{ fromJSON(env.BUILD_DOCKER) }}
|
|
id: buildx
|
|
uses: docker/setup-buildx-action@94ab11c41e45d028884a99163086648e898eed25
|
|
- name: Login to GitHub Container Registry
|
|
if: ${{ fromJSON(env.BUILD_DOCKER) }}
|
|
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ secrets.BOT_USERNAME }}
|
|
password: ${{ secrets.BOT_TOKEN }}
|
|
- name: Build concretefhe-env Image
|
|
if: ${{ success() && !cancelled() && fromJSON(env.BUILD_DOCKER) }}
|
|
uses: docker/build-push-action@a66e35b9cbcf4ad0ea91ffcaf7bbad63ad9e0229
|
|
with:
|
|
context: .
|
|
builder: ${{ steps.buildx.outputs.name }}
|
|
file: docker/Dockerfile.concretefhe-env
|
|
no-cache: true
|
|
push: true
|
|
tags: "${{ env.PREFLIGHT_IMAGE }}"
|
|
labels: |
|
|
concretefhe_sha=${{ env.LABEL_SHA1 }}
|
|
- name: Set notification report
|
|
id: report
|
|
if: ${{ always() }}
|
|
run: |
|
|
REPORT="Docker image preflight build ${{ env.PREFLIGHT_IMAGE }} finished with \
|
|
status ${{ job.status }}. Rebuilt image: ${{ env.BUILD_DOCKER || 'false' }}."
|
|
echo "${REPORT}"
|
|
echo "::set-output name=report::${REPORT}"
|
|
echo "REPORT=${REPORT}" >> "$GITHUB_ENV"
|
|
- name: Slack Notification
|
|
if: ${{ always() && !success() }}
|
|
continue-on-error: true
|
|
uses: rtCamp/action-slack-notify@12e36fc18b0689399306c2e0b3e0f2978b7f1ee7
|
|
env:
|
|
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
|
|
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
|
|
SLACK_COLOR: ${{ job.status }}
|
|
SLACK_MESSAGE: "${{ env.REPORT }} (${{ env.ACTION_RUN_URL }})"
|
|
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
|
|
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
|
|
|
build:
|
|
needs: [build-preflight-docker]
|
|
concurrency:
|
|
group: ${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
runs-on: ubuntu-20.04
|
|
container:
|
|
image: ${{ needs.build-preflight-docker.outputs.image }}
|
|
credentials:
|
|
username: ${{ secrets.BOT_USERNAME }}
|
|
password: ${{ secrets.BOT_TOKEN }}
|
|
defaults:
|
|
run:
|
|
shell: '/usr/bin/bash -e {0}'
|
|
strategy:
|
|
matrix:
|
|
# YAML footgun : https://twitter.com/webology/status/1445394072492023811?s=20
|
|
# Versions need to be quoted or risk being interpreted as floating point numbers
|
|
python-version: ["3.8"]
|
|
|
|
outputs:
|
|
report: ${{ steps.report.outputs.report || 'Did not run.' }}
|
|
|
|
steps:
|
|
- name: Checkout Code
|
|
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f
|
|
with:
|
|
fetch-depth: 0
|
|
- name: Set up Python ${{ matrix.python-version }}
|
|
uses: actions/setup-python@dc73133d4da04e56a135ae2246682783cc7c7cb6
|
|
with:
|
|
python-version: ${{ matrix.python-version }}
|
|
- name: Cache Installation Files
|
|
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
|
|
with:
|
|
# Paths are Unix specific for now
|
|
path: |
|
|
~/.cache/pip
|
|
~/.cache/pypoetry
|
|
# Ignore line break in the evaluated double quoted string
|
|
key: "${{ runner.os }}-build-${{ matrix.python-version }}-\
|
|
${{ hashFiles('poetry.lock') }}"
|
|
restore-keys: |
|
|
${{ runner.os }}-build-${{ matrix.python-version }}-
|
|
${{ runner.os }}-build-
|
|
${{ runner.os }}-
|
|
- name: Install dependencies
|
|
id: install-deps
|
|
run: |
|
|
python -m pip install --upgrade pip
|
|
python -m pip install poetry
|
|
make setup_env
|
|
- name: Check commits first line format
|
|
id: ccfl
|
|
if: ${{ fromJSON(env.IS_PR) && steps.install-deps.outcome == 'success' && !cancelled() }}
|
|
uses: gsactions/commit-message-checker@f27f413dcf8ebcb469d2ce4ae4e45e131d105de6
|
|
with:
|
|
pattern: '^((feat|fix|chore|refactor|style|test|docs)(\(\w+\))?\:) .+$'
|
|
flags: 'gs'
|
|
error: "Your first line has to contain a commit type and scope like \"feat(my_feature): msg\".\
|
|
Pattern: '^((feat|fix|chore|refactor|style|test|docs)(\\(\\w+\\))?\\:)'"
|
|
excludeDescription: 'true' # optional: this excludes the description body of a pull request
|
|
excludeTitle: 'true' # optional: this excludes the title of a pull request
|
|
checkAllCommitMessages: 'true' # optional: this checks all commits associated with a pull request
|
|
accessToken: ${{ secrets.GITHUB_TOKEN }} # github access token is only required if checkAllCommitMessages is true
|
|
- name: Check commits line length
|
|
id: ccll
|
|
if: ${{ fromJSON(env.IS_PR) && steps.install-deps.outcome == 'success' && !cancelled() }}
|
|
uses: gsactions/commit-message-checker@f27f413dcf8ebcb469d2ce4ae4e45e131d105de6
|
|
with:
|
|
pattern: '(^.{0,74}$\r?\n?){0,20}'
|
|
flags: 'gm'
|
|
error: 'The maximum line length of 74 characters is exceeded.'
|
|
excludeDescription: 'true' # optional: this excludes the description body of a pull request
|
|
excludeTitle: 'true' # optional: this excludes the title of a pull request
|
|
checkAllCommitMessages: 'true' # optional: this checks all commits associated with a pull request
|
|
accessToken: ${{ secrets.GITHUB_TOKEN }} # github access token is only required if checkAllCommitMessages is true
|
|
- name: Commit conformance
|
|
id: commit-conformance
|
|
if: ${{ steps.install-deps.outcome == 'success' && !cancelled() }}
|
|
env:
|
|
CCFL_OK: ${{ (fromJSON(env.IS_PR) && steps.ccfl.outcome == 'success') || steps.ccfl.outcome == 'skipped' }}
|
|
CCLL_OK: ${{ (fromJSON(env.IS_PR) && steps.ccll.outcome == 'success') || steps.ccll.outcome == 'skipped' }}
|
|
run: |
|
|
if [[ "${CCFL_OK}" != "true" || "${CCLL_OK}" != "true" ]]; then
|
|
echo "Issues with commits. First line ok: ${CCFL_OK}. Line length ok: ${CCLL_OK}."
|
|
exit 1
|
|
fi
|
|
- name: Source code Conformance
|
|
id: cs
|
|
if: ${{ steps.install-deps.outcome == 'success' && !cancelled() }}
|
|
# pcc launches an internal target with proper flags
|
|
run: |
|
|
make pcc
|
|
- name: Build docs
|
|
id: cbd
|
|
if: ${{ steps.install-deps.outcome == 'success' && !cancelled() }}
|
|
run: |
|
|
make docs
|
|
- name: Generate release changelog
|
|
id: changelog
|
|
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && steps.install-deps.outcome == 'success' && !cancelled() }}
|
|
run: |
|
|
GIT_TAG=$(echo "${{ github.ref }}" | sed 's/refs\/tags\///g')
|
|
CHANGELOG_FILE="CHANGELOG_${GIT_TAG}.md"
|
|
echo "::set-output name=changelog-file::${CHANGELOG_FILE}"
|
|
poetry run python ./script/make_utils/changelog_helper.py \
|
|
--to-ref "${GIT_TAG}" \
|
|
--to-ref-must-have-tag \
|
|
--ancestor-must-have-tag > "${CHANGELOG_FILE}"
|
|
- name: Conformance status
|
|
id: conformance
|
|
if: ${{ always() && !cancelled() }}
|
|
env:
|
|
CONFORMANCE_STATUS: ${{ steps.commit-conformance.outcome == 'success' && steps.cs.outcome == 'success' && steps.cbd.outcome == 'success' }}
|
|
run: |
|
|
if [[ "${CONFORMANCE_STATUS}" != "true" ]]; then
|
|
echo "Conformance failed, check logs"
|
|
exit 1
|
|
fi
|
|
- name: Archive docs artifacts
|
|
if: ${{ steps.conformance.outcome == 'success' && !cancelled() }}
|
|
uses: actions/upload-artifact@27121b0bdffd731efa15d66772be8dc71245d074
|
|
with:
|
|
name: html-docs
|
|
path: docs/_build/html
|
|
- name: Upload changelog artifacts
|
|
if: ${{ steps.changelog.outcome == 'success' && !cancelled() }}
|
|
uses: actions/upload-artifact@27121b0bdffd731efa15d66772be8dc71245d074
|
|
with:
|
|
name: changelog
|
|
path: ${{ steps.changelog.outputs.changelog-file }}
|
|
- name: PyTest Source Code
|
|
id: pytest
|
|
if: ${{ steps.conformance.outcome == 'success' && !cancelled() }}
|
|
run: |
|
|
make pytest
|
|
- name: Test CodeBlocks
|
|
if: ${{ steps.conformance.outcome == 'success' && !cancelled() }}
|
|
run: |
|
|
make test_codeblocks
|
|
- name: PyTest Notebooks
|
|
if: ${{ github.event_name == 'schedule' && steps.conformance.outcome == 'success' && !cancelled() }}
|
|
run: |
|
|
make pytest_nb
|
|
- name: Test coverage
|
|
id: coverage
|
|
if: ${{ always() && steps.pytest.outcome != 'skipped' && !cancelled() }}
|
|
run: |
|
|
./script/actions_utils/coverage.sh ${{ github.base_ref }}
|
|
- name: Archive test coverage
|
|
uses: actions/upload-artifact@27121b0bdffd731efa15d66772be8dc71245d074
|
|
if: ${{ steps.coverage.outcome != 'skipped' && !cancelled() }}
|
|
with:
|
|
name: coverage
|
|
path: coverage.html
|
|
- name: Comment with coverage
|
|
uses: marocchino/sticky-pull-request-comment@82e7a0d3c51217201b3fedc4ddde6632e969a477
|
|
if: ${{ steps.coverage.outcome != 'skipped' && !cancelled() }}
|
|
continue-on-error: true
|
|
with:
|
|
path: diff-coverage.txt
|
|
recreate: true
|
|
- name: Set notification report
|
|
id: report
|
|
if: ${{ always() }}
|
|
run: |
|
|
REPORT="Build finished with status ${{ job.status }}."
|
|
echo "${REPORT}"
|
|
echo "::set-output name=report::${REPORT}"
|
|
echo "REPORT=${REPORT}" >> "$GITHUB_ENV"
|
|
- name: Slack Notification
|
|
if: ${{ always() && !success() }}
|
|
continue-on-error: true
|
|
uses: rtCamp/action-slack-notify@12e36fc18b0689399306c2e0b3e0f2978b7f1ee7
|
|
env:
|
|
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
|
|
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
|
|
SLACK_COLOR: ${{ job.status }}
|
|
SLACK_MESSAGE: "${{ env.REPORT }} (${{ env.ACTION_RUN_URL }})"
|
|
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
|
|
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
|
|
|
publish-docs:
|
|
needs: [build]
|
|
concurrency:
|
|
group: ${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
outputs:
|
|
report: ${{ steps.report.outputs.report || 'Did not run.' }}
|
|
|
|
runs-on: ubuntu-20.04
|
|
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
|
|
|
steps:
|
|
- name: Download Documentation
|
|
id: download
|
|
uses: actions/download-artifact@3be87be14a055c47b01d3bd88f8fe02320a9bb60
|
|
with:
|
|
name: html-docs
|
|
|
|
- name: Publish Documentation to S3
|
|
id: publish
|
|
if: ${{ steps.download.outcome == 'success' && !cancelled() }}
|
|
uses: jakejarvis/s3-sync-action@be0c4ab89158cac4278689ebedd8407dd5f35a83
|
|
with:
|
|
args: --delete --acl public-read
|
|
env:
|
|
AWS_S3_BUCKET: ${{ secrets.AWS_REPO_DOCUMENTATION_BUCKET_NAME }}
|
|
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
AWS_REGION: ${{ secrets.AWS_REGION }}
|
|
SOURCE_DIR: '.'
|
|
DEST_DIR: 'concretefhe'
|
|
|
|
- name: Invalidate CloudFront Cache
|
|
if: ${{ steps.publish.outcome == 'success' }}
|
|
uses: awact/cloudfront-action@8bcfabc7b4bbc0cb8e55e48527f0e3a6d681627c
|
|
env:
|
|
SOURCE_PATH: '/concretefhe/*'
|
|
AWS_REGION: ${{ secrets.AWS_REGION }}
|
|
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
DISTRIBUTION_ID: ${{ secrets.AWS_REPO_DOCUMENTATION_DISTRIBUTION_ID }}
|
|
|
|
- name: Set notification report
|
|
id: report
|
|
if: ${{ always() }}
|
|
run: |
|
|
REPORT="Publishing documentation finished with status ${{ job.status }}."
|
|
echo "${REPORT}"
|
|
echo "::set-output name=report::${REPORT}"
|
|
echo "REPORT=${REPORT}" >> "$GITHUB_ENV"
|
|
|
|
- name: Slack Notification
|
|
if: ${{ always() && !success() }}
|
|
continue-on-error: true
|
|
uses: rtCamp/action-slack-notify@12e36fc18b0689399306c2e0b3e0f2978b7f1ee7
|
|
env:
|
|
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
|
|
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
|
|
SLACK_COLOR: ${{ job.status }}
|
|
SLACK_MESSAGE: "${{ env.REPORT }} (${{ env.ACTION_RUN_URL }})"
|
|
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
|
|
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
|
|
|
push-docker-image:
|
|
needs: [build-preflight-docker, build]
|
|
if: ${{ (github.event_name == 'push' && github.ref == 'refs/heads/main' && fromJSON(needs.build-preflight-docker.outputs.needs-push)) || fromJSON(needs.build-preflight-docker.outputs.force-rebuild-docker) }}
|
|
|
|
concurrency:
|
|
group: ${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
outputs:
|
|
report: ${{ steps.report.outputs.report || 'Did not run.' }}
|
|
|
|
name: Push env docker image
|
|
runs-on: ubuntu-20.04
|
|
env:
|
|
PREFLIGHT_IMAGE: ${{ needs.build-preflight-docker.outputs.image }}
|
|
|
|
steps:
|
|
- uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f
|
|
- name: Login to GitHub Container Registry
|
|
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ secrets.BOT_USERNAME }}
|
|
password: ${{ secrets.BOT_TOKEN }}
|
|
- name: Pull preflight image
|
|
run: |
|
|
docker pull "${PREFLIGHT_IMAGE}"
|
|
- name: Retag to latest and zamalang_sha1-concretefhe_sha1 and push
|
|
run: |
|
|
SHA1=$(git rev-parse HEAD)
|
|
ZAMALANG_SHA1=$(docker inspect "${PREFLIGHT_IMAGE}" | \
|
|
jq -rc '.[0].Config.Labels["commit-sha"]')
|
|
TAGGED_IMAGE="${BASE_IMAGE}:${ZAMALANG_SHA1}-${SHA1}"
|
|
docker tag "${PREFLIGHT_IMAGE}" "${LATEST_IMAGE}"
|
|
docker tag "${PREFLIGHT_IMAGE}" "${TAGGED_IMAGE}"
|
|
docker push "${LATEST_IMAGE}"
|
|
docker push "${TAGGED_IMAGE}"
|
|
|
|
- name: Set notification report
|
|
id: report
|
|
if: ${{ always() }}
|
|
run: |
|
|
REPORT="Pushing docker image ${{ env.BASE_IMAGE }} finished with status \
|
|
${{ job.status }}."
|
|
echo "${REPORT}"
|
|
echo "::set-output name=report::${REPORT}"
|
|
echo "REPORT=${REPORT}" >> "$GITHUB_ENV"
|
|
|
|
- name: Slack Notification
|
|
if: ${{ always() && !success() }}
|
|
continue-on-error: true
|
|
uses: rtCamp/action-slack-notify@12e36fc18b0689399306c2e0b3e0f2978b7f1ee7
|
|
env:
|
|
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
|
|
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
|
|
SLACK_COLOR: ${{ job.status }}
|
|
SLACK_MESSAGE: "${{ env.REPORT }} (${{ env.ACTION_RUN_URL }})"
|
|
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
|
|
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
|
|
|
package-release:
|
|
needs: [build]
|
|
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }}
|
|
|
|
concurrency:
|
|
group: ${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
outputs:
|
|
report: ${{ steps.report.outputs.report || 'Did not run.' }}
|
|
|
|
name: Prepare docker image release
|
|
runs-on: ubuntu-20.04
|
|
|
|
env:
|
|
RELEASE_IMAGE_BASE: ghcr.io/zama-ai/concretefhe
|
|
|
|
steps:
|
|
- uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f
|
|
# To be removed once poetry 1.2 is released to manage dependencies with groups
|
|
- name: Cache Installation Files
|
|
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
|
|
with:
|
|
# Paths are Unix specific for now
|
|
path: |
|
|
~/.cache/pip
|
|
~/.cache/pypoetry
|
|
# Use python 3.8 as it is the version available in ubuntu 20.04 and we develop with it
|
|
key: "${{ runner.os }}-build-3.8-${{ hashFiles('poetry.lock') }}"
|
|
restore-keys: |
|
|
${{ runner.os }}-build-3.8-
|
|
${{ runner.os }}-build-
|
|
${{ runner.os }}-
|
|
- name: Install dependencies
|
|
run: |
|
|
python -m pip install --upgrade pip
|
|
python -m pip install poetry
|
|
make setup_env
|
|
- name: Set tag in env
|
|
run: |
|
|
GIT_TAG=$(echo "${{ github.ref }}" | sed 's/refs\/tags\///g')
|
|
echo "GIT_TAG=${GIT_TAG}" >> "$GITHUB_ENV"
|
|
RELEASE_IMG_GIT_TAG="${RELEASE_IMAGE_BASE}:${GIT_TAG}"
|
|
echo "RELEASE_IMG_GIT_TAG=${RELEASE_IMG_GIT_TAG}" >> "$GITHUB_ENV"
|
|
RELEASE_IMG_TAGS_TO_PUSH="${RELEASE_IMG_GIT_TAG}"
|
|
|
|
EXISTING_TAGS=$(curl \
|
|
-X GET \
|
|
-H "Authorization: Bearer $(echo ${{ secrets.BOT_TOKEN }} | base64)" \
|
|
https://ghcr.io/v2/zama-ai/concretefhe/tags/list | jq -rc '.tags | join(" ")')
|
|
|
|
# We want the space separated list of versions to be expanded
|
|
# shellcheck disable=SC2086
|
|
IS_LATEST_INFO=$(poetry run python script/make_utils/version_utils.py \
|
|
islatest \
|
|
--new-version "${GIT_TAG}" \
|
|
--existing-versions $EXISTING_TAGS)
|
|
|
|
REQUIRES_LATEST_TAG=$(echo "${IS_LATEST_INFO}" | jq -rc '.is_latest')
|
|
IS_PRERELEASE=$(echo "${IS_LATEST_INFO}" | jq -rc '.is_prerelease')
|
|
echo "IS_PRERELEASE=${IS_PRERELEASE}" >> "$GITHUB_ENV"
|
|
|
|
if [[ "${REQUIRES_LATEST_TAG}" == "true" ]]; then
|
|
RELEASE_IMG_LATEST_TAG="${RELEASE_IMAGE_BASE}:latest"
|
|
RELEASE_IMG_TAGS_TO_PUSH="${RELEASE_IMG_TAGS_TO_PUSH},${RELEASE_IMG_LATEST_TAG}"
|
|
fi
|
|
|
|
echo "RELEASE_IMG_TAGS_TO_PUSH=${RELEASE_IMG_TAGS_TO_PUSH}" >> "$GITHUB_ENV"
|
|
- name: Set up Docker Buildx
|
|
id: buildx
|
|
uses: docker/setup-buildx-action@94ab11c41e45d028884a99163086648e898eed25
|
|
- name: Login to GitHub Container Registry
|
|
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ secrets.BOT_USERNAME }}
|
|
password: ${{ secrets.BOT_TOKEN }}
|
|
- name: Build concretefhe Image
|
|
if: ${{ success() && !cancelled() }}
|
|
uses: docker/build-push-action@a66e35b9cbcf4ad0ea91ffcaf7bbad63ad9e0229
|
|
with:
|
|
context: .
|
|
builder: ${{ steps.buildx.outputs.name }}
|
|
file: docker/Dockerfile.release
|
|
load: true
|
|
push: false
|
|
tags: "${{ env.RELEASE_IMG_TAGS_TO_PUSH }}"
|
|
no-cache: true
|
|
- name: Release image sanity check and push
|
|
if: ${{ success() && !cancelled() }}
|
|
run: |
|
|
echo "Running sanity check for ${RELEASE_IMG_GIT_TAG}"
|
|
docker run --rm -v "$(pwd)"/docker/release_resources:/data \
|
|
"${RELEASE_IMG_GIT_TAG}" /bin/bash -c "python ./sanity_check.py"
|
|
docker image push --all-tags "${RELEASE_IMAGE_BASE}"
|
|
- name: Create directory for artifacts
|
|
if: ${{ success() && !cancelled() }}
|
|
run: |
|
|
ARTIFACTS_RAW_DIR=/tmp/release_artifacts/raw/
|
|
mkdir -p "${ARTIFACTS_RAW_DIR}"
|
|
echo "ARTIFACTS_RAW_DIR=${ARTIFACTS_RAW_DIR}" >> "$GITHUB_ENV"
|
|
|
|
ARTIFACTS_PACKAGED_DIR=/tmp/release_artifacts/packaged/
|
|
mkdir -p "${ARTIFACTS_PACKAGED_DIR}"
|
|
echo "ARTIFACTS_PACKAGED_DIR=${ARTIFACTS_PACKAGED_DIR}" >> "$GITHUB_ENV"
|
|
- name: Download Documentation
|
|
if: ${{ success() && !cancelled() }}
|
|
id: download-docs
|
|
uses: actions/download-artifact@3be87be14a055c47b01d3bd88f8fe02320a9bb60
|
|
with:
|
|
name: html-docs
|
|
path: ${{ env.ARTIFACTS_RAW_DIR }}/html_docs/
|
|
- name: Download changelog
|
|
if: ${{ success() && !cancelled() }}
|
|
id: download-changelog
|
|
uses: actions/download-artifact@3be87be14a055c47b01d3bd88f8fe02320a9bb60
|
|
with:
|
|
name: changelog
|
|
path: ${{ env.ARTIFACTS_RAW_DIR }}/changelog/
|
|
- name: Create ready to upload/packaged artifacts
|
|
if: ${{ success() && !cancelled() }}
|
|
env:
|
|
RAW_DOCS_DIR: ${{ steps.download-docs.outputs.download-path }}
|
|
RAW_CHANGELOG_DIR: ${{ steps.download-changelog.outputs.download-path }}
|
|
run: |
|
|
pushd "${RAW_DOCS_DIR}"
|
|
zip -r "${ARTIFACTS_PACKAGED_DIR}/html-docs.zip" ./*
|
|
tar -cvzf "${ARTIFACTS_PACKAGED_DIR}/html-docs.tar.gz" ./*
|
|
popd
|
|
cp "${RAW_CHANGELOG_DIR}/*" "${ARTIFACTS_PACKAGED_DIR}"
|
|
- name: Create GitHub release
|
|
if: ${{ success() && !cancelled() }}
|
|
id: create-release
|
|
uses: softprops/action-gh-release@6034af24fba4e5a8e975aaa6056554efe4c794d0
|
|
with:
|
|
body: |
|
|
**Docker Image:** ${{ env.RELEASE_IMG_GIT_TAG }}
|
|
**Documentation:** https://docs.zama.ai/concrete/
|
|
prerelease: ${{ fromJSON(env.IS_PRERELEASE) }}
|
|
files: |
|
|
'${{ env.ARTIFACTS_PACKAGED_DIR }}/*'
|
|
tag_name: ${{ env.GIT_TAG }}
|
|
fail_on_unmatched_files: true
|
|
token: ${{ secrets.BOT_TOKEN }}
|
|
- name: Set notification report
|
|
id: report
|
|
if: ${{ always() }}
|
|
run: |
|
|
REPORT="Creating release for ${GIT_TAG} finished with status ${{ job.status }}. \
|
|
GitHub release link: ${{ steps.create-release.outputs.url }}."
|
|
echo "${REPORT}"
|
|
echo "::set-output name=report::${REPORT}"
|
|
echo "REPORT=${REPORT}" >> "$GITHUB_ENV"
|
|
- name: Slack Notification
|
|
if: ${{ always() && !success() }}
|
|
continue-on-error: true
|
|
uses: rtCamp/action-slack-notify@12e36fc18b0689399306c2e0b3e0f2978b7f1ee7
|
|
env:
|
|
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
|
|
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
|
|
SLACK_COLOR: ${{ job.status }}
|
|
SLACK_MESSAGE: "${{ env.REPORT }} (${{ env.ACTION_RUN_URL }})"
|
|
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
|
|
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
|
|
|
send-report:
|
|
if: ${{ always() }}
|
|
needs:
|
|
[
|
|
build-preflight-docker,
|
|
build,
|
|
publish-docs,
|
|
push-docker-image,
|
|
package-release,
|
|
]
|
|
|
|
name: Send Slack notification
|
|
runs-on: ubuntu-20.04
|
|
steps:
|
|
- uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f
|
|
- name: Prepare whole job status
|
|
if: ${{ always() }}
|
|
continue-on-error: true
|
|
env:
|
|
NEEDS_JSON: ${{ toJSON(needs) }}
|
|
run: |
|
|
echo "${NEEDS_JSON}" > /tmp/needs_context.json
|
|
JOB_STATUS=$(python3 ./script/actions_utils/actions_combine_status.py \
|
|
--needs_context_json /tmp/needs_context.json)
|
|
echo "JOB_STATUS=${JOB_STATUS}" >> "$GITHUB_ENV"
|
|
|
|
- name: Slack Notification
|
|
if: ${{ always() }}
|
|
continue-on-error: true
|
|
uses: rtCamp/action-slack-notify@12e36fc18b0689399306c2e0b3e0f2978b7f1ee7
|
|
env:
|
|
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
|
|
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
|
|
SLACK_COLOR: ${{ env.JOB_STATUS || 'failure' }}
|
|
SLACK_MESSAGE: "Full run finished with status ${{ env.JOB_STATUS || 'failure' }} \
|
|
(${{ env.ACTION_RUN_URL }})\n\
|
|
- build-preflight-docker: ${{ needs.build-preflight-docker.outputs.report || 'Did not run.' }}\n\n\
|
|
- build: ${{ needs.build.outputs.report || 'Did not run.' }}\n\n\
|
|
- publish-docs: ${{ needs.publish-docs.outputs.report || 'Did not run.' }}\n\n\
|
|
- push-docker-image: ${{ needs.push-docker-image.outputs.report || 'Did not run.' }}\n\n\
|
|
- package-release: ${{ needs.package-release.outputs.report || 'Did not run.' }}"
|
|
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
|
|
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|