CI #612
This file contains hidden or 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: 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 }} |