Skip to content

CI

CI #612

Workflow file for this run

name: CI
# This workflow builds all the images defined in images.json with the specified
# dependencies, and runs a set of locally defined tests.
#
# Each image defined in images.json specifies the events the image should be
# rebuilt and pushed. Most images will do so for push and pull_request, but can
# also be specified to build on a schedule.
#
# The tests in this repo are designed to make sure that when quickstart starts
# up it is able to either sync with an existing network, or start a new network
# that is progressing.
#
# This workflow also tests that the quickstart action functions.
on:
push:
branches:
- main
pull_request:
schedule:
- cron: '0 19,1 * * *' # approx 12pm, 6pm SF time
# Prevent more than one build of this workflow for a branch to be running at the
# same time, and if multiple are queued, only run the latest, cancelling any
# already running build. The exception being any protected branch, such as
# main, where a build for every commit will run.
concurrency:
group: ${{ github.workflow }}-${{ github.ref_protected == true && github.sha || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
complete:
if: always()
name: complete
needs: [build, test, action-using-artifact, push, action-using-registry]
runs-on: ubuntu-latest
steps:
- if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: exit 1
setup:
name: 1 setup
runs-on: ubuntu-latest
outputs:
sha: ${{ steps.sha.outputs.sha }}
tag-prefix: ${{ steps.tag-prefix.outputs.tag-prefix }}
tag-alias-prefix: ${{ steps.tag-prefix.outputs.tag-alias-prefix }}
images: ${{ steps.images.outputs.images }}
tags: ${{ steps.tags.outputs.tags }}
archs: ${{ steps.archs.outputs.archs }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0 # Get all history for the sha count below.
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Sha
id: sha
run: |
echo "sha=$(git rev-parse HEAD)" | tee -a $GITHUB_OUTPUT
- name: Tag Prefix
id: tag-prefix
run: |
pr_prefix="${{ github.event_name == 'pull_request' && format('pr{0}-', github.event.pull_request.number) || '' }}"
commit_count="$(git rev-list HEAD --count --first-parent)"
build_number="${{ github.run_number }}.${{ github.run_attempt }}"
echo "tag-prefix=${pr_prefix}v${commit_count}-b${build_number}-" | tee -a $GITHUB_OUTPUT
echo "tag-alias-prefix=${pr_prefix}" | tee -a $GITHUB_OUTPUT
- name: Images
id: images
run: |
images="$(<images.json)"
images="$(<<< $images jq -c --arg event "${{ github.event_name }}" '[.[] | select(.events | contains([$event]))]')"
<<< $images jq
echo "images=$images" >> $GITHUB_ENV
echo "images=$images" >> $GITHUB_OUTPUT
- name: Tags
id: tags
run: |
tags="$(<<< $images jq -c '[.[].tag]')"
<<< $tags jq
echo "tags=$tags" >> $GITHUB_OUTPUT
- name: Architectures
id: archs
run: |
archs='["amd64","arm64"]'
<<< $archs jq
echo "archs=$archs" >> $GITHUB_OUTPUT
build:
name: 2 build
needs: setup
uses: ./.github/workflows/internal-build.yml
with:
repo: ${{ github.repository }}
sha: ${{ needs.setup.outputs.sha }}
images: ${{ needs.setup.outputs.images }}
archs: ${{ needs.setup.outputs.archs }}
test:
name: 3 test
needs: [setup, build]
uses: ./.github/workflows/internal-test.yml
with:
repo: ${{ github.repository }}
sha: ${{ needs.setup.outputs.sha }}
images: ${{ needs.setup.outputs.images }}
archs: ${{ needs.setup.outputs.archs }}
action-using-artifact:
needs: [setup, build]
name: 4 test action artifact
uses: ./.github/workflows/internal-action-test.yml
with:
artifact: image-quickstart-${{ fromJSON(needs.setup.outputs.tags)[0] }}-${{ fromJSON(needs.setup.outputs.archs)[0] }}.tar
tag: ${{ fromJSON(needs.setup.outputs.tags)[0] }}-${{ fromJSON(needs.setup.outputs.archs)[0] }}
push:
if: ((github.event_name == 'push' || github.event_name == 'schedule') && github.ref == 'refs/heads/main') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
name: 5 push
needs: [setup, build]
uses: ./.github/workflows/internal-push.yml
with:
sha: ${{ needs.setup.outputs.sha }}
tags: ${{ needs.setup.outputs.tags }}
archs: ${{ needs.setup.outputs.archs }}
tag-prefix: ${{ needs.setup.outputs.tag-prefix }}
tag-alias-prefix: ${{ needs.setup.outputs.tag-alias-prefix }}
registry_repo: ${{ github.repository }}
secrets:
registry: ${{ secrets.DOCKERHUB_TOKEN && 'docker.io' || 'ghcr.io' }}
registry_username: ${{ secrets.DOCKERHUB_USERNAME || github.actor }}
registry_password: ${{ secrets.DOCKERHUB_TOKEN || github.token }}
action-using-registry:
if: ((github.event_name == 'push' || github.event_name == 'schedule') && github.ref == 'refs/heads/main') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
needs: [setup, push]
name: 6 test action registry
uses: ./.github/workflows/internal-action-test.yml
with:
tag: ${{ needs.setup.outputs.tag-prefix }}${{ fromJSON(needs.setup.outputs.tags)[0] }}
notify:
name: 7 slack notify on failure
if: always() && github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'schedule') && contains(needs.*.result, 'failure')
needs: [setup, build, test, push]
runs-on: ubuntu-latest
continue-on-error: true
steps:
- name: Generate cache key from images config
id: cache_key
env:
images: ${{ needs.setup.outputs.images }}
run: |
cache_key=$(<<< $images jq -cS '.' | sha256sum | awk '{print $1}')
echo "key=notify-$cache_key" >> $GITHUB_OUTPUT
- name: Restore notification cache
id: cache_restore
uses: actions/cache/restore@v4
with:
path: .notify_cache
key: ${{ steps.cache_key.outputs.key }}
- name: Send Slack notification
if: steps.cache_restore.outputs.cache-hit != 'true'
env:
slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
event: ${{ github.event_name }}
sha: ${{ github.sha }}
build_emoji: ${{ needs.build.result == 'success' && '✅' || needs.build.result == 'failure' && '❌' || '❓' }}
test_emoji: ${{ needs.test.result == 'success' && '✅' || needs.test.result == 'failure' && '❌' || '❓' }}
push_emoji: ${{ needs.push.result == 'success' && '✅' || needs.push.result == 'failure' && '❌' || '❓' }}
commit_url: https://github.com/${{ github.repository }}/commit/${{ github.sha }}
run_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
short_sha="${sha:0:7}"
payload="$(jq -n \
--arg build "$build_emoji" \
--arg test "$test_emoji" \
--arg push "$push_emoji" \
--arg event "$event" \
--arg short_sha "$short_sha" \
--arg commit_url "$commit_url" \
--arg run_url "$run_url" \
'{text: ":red_circle: • build \($build) • test \($test) • push \($push) • <\($commit_url)|\($short_sha)> • <\($run_url)|run> • \($event)"}')"
curl -X POST "$slack_webhook_url" \
-H 'Content-Type: application/json' \
-d "$payload"
- name: Create cache file
if: steps.cache_restore.outputs.cache-hit != 'true'
run: |
mkdir -p .notify_cache
echo "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" > .notify_cache/timestamp
- name: Save notification cache
if: steps.cache_restore.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: .notify_cache
key: ${{ steps.cache_key.outputs.key }}