Nightly builds of SimApp (Cosmos-SDK) #6
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: Nightly builds of SimApp (Cosmos-SDK) | |
# CI (Continuous Integration) workflow that creates nightly builds of SimApp (Cosmos-SDK). | |
# 1. Builds multi-arch and multiples major versions in parallel | |
# 2. Checks that the output binary is working correctly by initiating a testchain and verifying that blocks are procuced | |
# OUTPUTS: | |
# - One github workflow artefact for each binary | |
# - One multi-arch tag for each major version on the container image | |
on: | |
schedule: | |
- cron: 0 0 * * * # Every day at 0:00 UTC | |
workflow_dispatch: | |
permissions: | |
packages: write | |
contents: write | |
env: | |
RELEASE_NAME: cosmos-sdk | |
concurrency: | |
group: ${{ github.workflow }} | |
cancel-in-progress: true | |
jobs: | |
build-cosmos-sdk: | |
runs-on: ubuntu-latest | |
outputs: | |
date: ${{ steps.archive.outputs.date }} | |
strategy: | |
matrix: | |
go-arch: [amd64, arm64] | |
major-version: [v0.50.x, v0.52.x] | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
repository: cosmos/cosmos-sdk | |
ref: release/${{ matrix.major-version }} | |
token: ${{ github.token }} | |
path: cosmos-sdk | |
- uses: actions/setup-go@v5 | |
with: | |
go-version: "1.23" | |
check-latest: true | |
- name: Create application binary | |
id: build | |
run: | | |
cd cosmos-sdk | |
GOARCH=${{ matrix.go-arch }} make install | |
echo "gobin=$(go env GOPATH)/bin" >> $GITHUB_OUTPUT | |
- name: Run and monitor application | |
shell: bash | |
# no arm64 runners as of now : https://github.com/orgs/community/discussions/19197 | |
if: ${{ matrix.go-arch == 'amd64' }} | |
run: | | |
set -oue pipefail | |
set -x | |
# Set the timeout to 60 seconds | |
TIMEOUT=60 | |
START_TIME=$(date +%s) | |
cd cosmos-sdk | |
make init-simapp | |
simd start > ./output.log 2>1 & | |
APP_PID=$! | |
while true; do | |
CURRENT_TIME=$(date +%s) | |
ELAPSED_TIME=$((CURRENT_TIME - START_TIME)) | |
if [ $ELAPSED_TIME -ge $TIMEOUT ]; then | |
echo "Timeout reached. Application did not produce the success pattern within 60 seconds." | |
kill $APP_PID | |
cat ./output.log | |
exit 1 | |
fi | |
# Check that 4th block is produced to validate the application | |
if simd query block-results 4; then | |
echo "Block #4 has been committed. Application is working correctly." | |
kill $APP_PID | |
exit 0 | |
else | |
echo "Block height is not greater than 4." | |
fi | |
sleep 3 | |
done | |
- name: Create archive | |
id: archive | |
run: | | |
set -oue pipefail | |
set -x | |
date=$(date +'%Y%m%d') | |
echo "date=$date" >> $GITHUB_ENV | |
echo "date=$date" >> $GITHUB_OUTPUT | |
# Create archive | |
SIMD_PATH=$(find $(go env GOPATH)/bin | tail -n 1) | |
mv $SIMD_PATH ${{ github.workspace }}/${{ env.RELEASE_NAME }}-${{ matrix.major-version }}-$date-${{ matrix.go-arch }} | |
- name: Upload Artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ env.RELEASE_NAME }}-${{ matrix.major-version }}-${{ env.date }}-${{ matrix.go-arch }} | |
path: ${{ github.workspace }}/${{ env.RELEASE_NAME }}-${{ matrix.major-version }}-${{ env.date }}-${{ matrix.go-arch }} | |
retention-days: 10 | |
- name: Setup Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Login to GitHub Container Registry | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: "${{ github.actor }}" | |
password: "${{ secrets.GITHUB_TOKEN }}" | |
- name: Setup Goss | |
if: ${{ matrix.go-arch == 'amd64' }} | |
uses: e1himself/goss-installation-action@v1 | |
with: | |
version: v0.4.4 | |
- name: Lowercase repository owner | |
shell: bash | |
run: echo "LOWERCASE_REPO_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> "${GITHUB_ENV}" | |
- name: Prepare Build Outputs | |
id: prepare-build-outputs | |
shell: bash | |
run: | | |
image_name="ghcr.io/${{ env.LOWERCASE_REPO_OWNER }}/${{ env.RELEASE_NAME }}" | |
outputs="type=image,name=${image_name},push-by-digest=true,name-canonical=true,push=true" | |
echo "image_name=${image_name}" >> $GITHUB_OUTPUT | |
echo "outputs=${outputs}" >> $GITHUB_OUTPUT | |
- uses: actions/checkout@v4 | |
with: | |
path: nightly-stack | |
- uses: actions/download-artifact@v4 | |
with: | |
name: ${{ env.RELEASE_NAME }}-${{ matrix.major-version }}-${{ env.date }}-${{ matrix.go-arch }} | |
path: nightly-stack/containers/cosmos-sdk | |
- name: Build Image | |
uses: docker/build-push-action@v6 | |
id: build-image | |
with: | |
build-args: |- | |
BINARY=${{ env.RELEASE_NAME }}-${{ matrix.major-version }}-${{ env.date }}-${{ matrix.go-arch }} | |
context: ./nightly-stack/containers/cosmos-sdk | |
file: ./nightly-stack/containers/cosmos-sdk/Dockerfile | |
platforms: ${{ matrix.go-arch }} | |
outputs: ${{ steps.prepare-build-outputs.outputs.outputs }} | |
cache-from: type=gha | |
cache-to: type=gha,mode=max | |
labels: |- | |
org.opencontainers.image.title=${{ steps.prepare-build-outputs.outputs.image_name }} | |
org.opencontainers.image.url=https://ghcr.io/${{ env.LOWERCASE_REPO_OWNER }}/${{ steps.prepare-build-outputs.outputs.image_name }} | |
org.opencontainers.image.source=https://github.com/${{ env.LOWERCASE_REPO_OWNER }}/containers | |
org.opencontainers.image.version=${{ matrix.major-version }} | |
org.opencontainers.image.revision=${{ github.sha }} | |
org.opencontainers.image.vendor=${{ env.LOWERCASE_REPO_OWNER }} | |
- name: Run Goss Tests | |
id: dgoss | |
if: ${{ matrix.go-arch == 'amd64' }} | |
env: | |
CONTAINER_RUNTIME: docker | |
GOSS_FILES_PATH: ${{ github.workspace }}/nightly-stack/containers/cosmos-sdk/ci | |
GOSS_OPTS: --retry-timeout 60s --sleep 2s --color --format documentation | |
GOSS_SLEEP: 2 | |
GOSS_FILES_STRATEGY: cp | |
CONTAINER_LOG_OUTPUT: goss_container_log_output | |
shell: bash | |
run: | | |
set -x | |
ls -l ${{ github.workspace }}/nightly-stack/containers/cosmos-sdk/ci/goss.yaml | |
image_name="${{ steps.prepare-build-outputs.outputs.image_name }}@${{ steps.build-image.outputs.digest }}" | |
dgoss run ${image_name} | |
- name: Export Digest | |
id: export-digest | |
shell: bash | |
run: | | |
mkdir -p /tmp/${{ env.RELEASE_NAME }}/digests | |
digest="${{ steps.build-image.outputs.digest }}" | |
echo "${{ env.RELEASE_NAME }}" > "/tmp/${{ env.RELEASE_NAME }}/digests/${digest#sha256:}" | |
- name: Upload Digest | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ env.RELEASE_NAME }}-${{ matrix.major-version }}-${{ matrix.go-arch }} | |
path: /tmp/${{ env.RELEASE_NAME }}/* | |
if-no-files-found: error | |
retention-days: 1 | |
merge: | |
name: Merge cosmos-sdk | |
runs-on: ubuntu-latest | |
needs: [build-cosmos-sdk] | |
if: ${{ always() }} | |
strategy: | |
matrix: | |
major-version: [v0.50.x, v0.52.x] | |
fail-fast: false | |
steps: | |
- name: Set variables | |
id: variables | |
shell: bash | |
run: | | |
set -x | |
echo "LOWERCASE_REPO_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV | |
major_version_clean=${{ matrix.major-version }} | |
major_version_clean=${major_version_clean#v} | |
major_version_clean=${major_version_clean%.x} | |
echo "LOWERCASE_REPO_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV | |
echo "MAJOR_VERSION_CLEAN=${major_version_clean}" >> $GITHUB_OUTPUT | |
- name: Download Digests | |
uses: actions/download-artifact@v4 | |
with: | |
pattern: "${{ env.RELEASE_NAME }}-${{ matrix.major-version }}-{amd64,arm64}" | |
merge-multiple: true | |
path: /tmp/cosmos-sdk | |
- name: Setup Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Login to GitHub Container Registry | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: "${{ github.actor }}" | |
password: "${{ secrets.GITHUB_TOKEN }}" | |
- name: Log Files | |
working-directory: /tmp/cosmos-sdk/digests | |
shell: bash | |
run: | | |
ls -la | |
cat * | |
- name: Merge Manifests | |
id: merge | |
working-directory: /tmp/cosmos-sdk/digests | |
shell: bash | |
run: | | |
set -x | |
docker buildx imagetools create \ | |
--tag ghcr.io/${{ env.LOWERCASE_REPO_OWNER }}/${{ env.RELEASE_NAME }}:${{ steps.variables.outputs.MAJOR_VERSION_CLEAN }} \ | |
$(printf 'ghcr.io/${{ env.LOWERCASE_REPO_OWNER }}/${{ env.RELEASE_NAME }}@sha256:%s ' *) | |
- name: Inspect image | |
id: inspect | |
shell: bash | |
run: | | |
docker buildx imagetools inspect ghcr.io/${{ env.LOWERCASE_REPO_OWNER }}/${{ env.RELEASE_NAME }}:${{ steps.variables.outputs.MAJOR_VERSION_CLEAN }} | |
- name: Build successful | |
id: build-success | |
if: ${{ always() && steps.merge.outcome == 'success' && steps.inspect.outcome == 'success' }} | |
shell: bash | |
run: | | |
echo "message=🎉 ${{ env.RELEASE_NAME }} (${{ needs.build-cosmos-sdk.outputs.date }})" >> $GITHUB_OUTPUT | |
echo "color=0x00FF00" >> $GITHUB_OUTPUT | |
- name: Build failed | |
id: build-failed | |
if: ${{ always() && (steps.merge.outcome == 'failure' || steps.inspect.outcome == 'failure') }} | |
shell: bash | |
run: | | |
echo "message=💥 ${{ env.RELEASE_NAME }} (${{ needs.build-cosmos-sdk.outputs.date }})" >> $GITHUB_OUTPUT | |
echo "color=0xFF0000" >> $GITHUB_OUTPUT | |
# Summarize matrix https://github.community/t/status-check-for-a-matrix-jobs/127354/7 | |
build_success: | |
name: Build matrix success | |
runs-on: ubuntu-latest | |
needs: [merge] | |
if: ${{ always() }} | |
steps: | |
- name: Check build matrix status | |
if: ${{ needs.merge.result != 'success' && needs.merge.result != 'skipped' }} | |
shell: bash | |
run: exit 1 | |
sims-notify-success: | |
needs: merge | |
runs-on: ubuntu-latest | |
if: ${{ success() }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Get previous workflow status | |
uses: cosmos/cosmos-sdk/.github/actions/last-workflow-status@main | |
id: last_status | |
with: | |
github_token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Notify Slack on success | |
if: ${{ steps.last_status.outputs.last_status == 'failure' }} | |
uses: rtCamp/[email protected] | |
env: | |
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |
SLACK_CHANNEL: nightly-stack-build | |
SLACK_USERNAME: Nightly Builds | |
SLACK_ICON_EMOJI: ":white_check_mark:" | |
SLACK_COLOR: good | |
SLACK_MESSAGE: ${{ env.RELEASE_NAME }} is passing | |
SLACK_FOOTER: "" | |
sims-notify-failure: | |
permissions: | |
contents: none | |
needs: merge | |
runs-on: ubuntu-latest | |
if: ${{ failure() }} | |
steps: | |
- name: Notify Slack on failure | |
uses: rtCamp/[email protected] | |
env: | |
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |
SLACK_CHANNEL: nightly-stack-build | |
SLACK_USERNAME: Nightly Builds | |
SLACK_ICON_EMOJI: ":skull:" | |
SLACK_COLOR: danger | |
SLACK_MESSAGE: ${{ env.RELEASE_NAME }} is failing | |
SLACK_FOOTER: "" |