diff --git a/.github/scripts/update-go-dependencies.sh b/.github/scripts/update-go-dependencies.sh new file mode 100755 index 0000000..6651815 --- /dev/null +++ b/.github/scripts/update-go-dependencies.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +set -oue pipefail + +COSMOSSDK_BRANCH=${COSMOSSDK_BRANCH:-refs/heads/release/v0.50.x} + +# Function to get the latest commit SHA for a given repo and branch +get_latest_commit() { + local repo=$1 + local branch=$2 + git ls-remote "https://github.com/${repo}.git" "${branch}" | cut -f1 +} + +# Function to get pseudo-version from commit SHA +get_pseudo_version() { + local repo=$1 + local commit_sha=$2 + + pseudo_version=$(go list -m -f '{{.Version}}' $repo@$commit_sha 2>/dev/null) + + if [ -z "$pseudo_version" ]; then + echo "Error: Unable to find pseudo-version for $repo@$commit_sha" + return 1 + else + echo "${pseudo_version}" + fi +} + +get_and_update_module() { + local commit=$1 + pseudo_version=$(get_pseudo_version "$module" "$commit") + + echo "Updating $module to pseudo-version $pseudo_version" + + go mod edit -replace=$module=$module@$pseudo_version + + if ! go mod download $module@$pseudo_version; then + echo "Download failed. Trying with a different commit." + return 1 + fi + + return 0 +} + +# Extract module paths and versions from go.mod on current folder +modules=$(go mod edit --json | jq -r '.Require[] | select(.Path | contains("/")) | .Path') + +latest_commit_main=$(get_latest_commit "cosmos/cosmos-sdk" "main") +echo "cosmos/cosmos-sdk main latest_commit: $latest_commit_main" +latest_commit_branch=$(get_latest_commit "cosmos/cosmos-sdk" "$COSMOSSDK_BRANCH") +echo "cosmos/cosmos-sdk $COSMOSSDK_BRANCH latest_commit: $latest_commit_branch" + +# Version override logic +for module in $modules; do + + echo "module: $module" + + if [[ $module =~ "cosmossdk.io" ]]; then + if ! get_and_update_module "$latest_commit_branch"; then + # If it fails, get the from main + if ! get_and_update_module "$latest_commit_main"; then + echo "Failed to update module after trying $COSMOSSDK_BRANCH and main." + exit 1 + fi + fi + elif [[ $module == "github.com/cosmos/cosmos-sdk" ]]; then + # modules that need to follow HEAD on release branch + pseudo_version=$(get_pseudo_version "github.com/cosmos/cosmos-sdk" $latest_commit_branch) + echo "Updating $module to pseudo-version $pseudo_version" + go mod edit -replace=$module=$module@$pseudo_version + go mod download $module@$pseudo_version + fi +done + +go mod verify +go mod tidy diff --git a/.github/workflows/release-cosmos-sdk.yaml b/.github/workflows/nightly-1-release-cosmos-sdk.yaml similarity index 100% rename from .github/workflows/release-cosmos-sdk.yaml rename to .github/workflows/nightly-1-release-cosmos-sdk.yaml diff --git a/.github/workflows/test-cosmos-sdk-comet.yml b/.github/workflows/nightly-2-test-cosmos-sdk-comet.yml similarity index 100% rename from .github/workflows/test-cosmos-sdk-comet.yml rename to .github/workflows/nightly-2-test-cosmos-sdk-comet.yml diff --git a/.github/workflows/nightly-3-release-ibc-go.yml b/.github/workflows/nightly-3-release-ibc-go.yml new file mode 100644 index 0000000..d95d75d --- /dev/null +++ b/.github/workflows/nightly-3-release-ibc-go.yml @@ -0,0 +1,339 @@ +name: Release IBC-go +# CI (Continuous Integration) workflow that creates nightly builds of SimApp (IBC-go). +# 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: IBC-go@main + cosmos-sdk modules@HEAD + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + +jobs: + build-wfl3: + runs-on: ubuntu-latest + outputs: + date: ${{ steps.archive.outputs.date }} + strategy: + matrix: + go-arch: [amd64, arm64] + steps: + - uses: actions/checkout@v4 + with: + repository: cosmos/ibc-go + ref: main + token: ${{ github.token }} + path: ibc-go + + - uses: actions/checkout@v4 + with: + path: nightly-stack + + - uses: actions/setup-go@v5 + with: + go-version: "1.23" + check-latest: true + + - name: Update cosmos-sdk modules to HEAD/main + run: | + cd ibc-go/simapp + ../../nightly-stack/.github/scripts/update-go-dependencies.sh + + - name: DEBUG update-go-dependencies.sh + run: | + cat ibc-go/simapp/go.mod + cat ibc-go/simapp/go.sum + + - name: Create application binary + id: build + run: | + cd ibc-go + GOARCH=${{ matrix.go-arch }} make build + 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 ibc-go + 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 }}-$date-${{ matrix.go-arch }} + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ env.RELEASE_NAME }}-${{ env.date }}-${{ matrix.go-arch }} + path: ${{ github.workspace }}/${{ env.RELEASE_NAME }}-${{ 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/download-artifact@v4 + with: + name: ${{ env.RELEASE_NAME }}-${{ 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 }}-${{ 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=main + 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.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-wfl3] + if: ${{ always() }} + steps: + - name: Set variables + id: variables + shell: bash + run: | + set -x + echo "LOWERCASE_REPO_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + echo "LOWERCASE_REPO_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + echo "MAJOR_VERSION_CLEAN=main" >> $GITHUB_OUTPUT + + - name: Download Digests + uses: actions/download-artifact@v4 + with: + pattern: "${{ env.RELEASE_NAME }}-{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-wfl3.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-wfl3.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/action-slack-notify@v2.3.0 + 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/action-slack-notify@v2.3.0 + 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: "" diff --git a/README.md b/README.md index 74bc2af..aa00c43 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,27 @@ ![Knight Battle testing](./knightly.jpeg) -This repository contains the nightly build of the Interchain Stack. The Interchain Stack is a collection of software that enables the creation of decentralized applications that are interoperable with other blockchains. The stack includes the Cosmos SDK, IBC, and CW. +This repository contains the nightly builds of the Interchain Stack. The Interchain Stack is a collection of software that enables the creation of decentralized applications that are interoperable with other blockchains. The stack includes the Cosmos SDK, IBC, and CW. + +## Workflows description + +### Workflow #1 - Release Cosmos-SDK +- Application: SimApp from `cosmos/cosmos-sdk` +- Dependencies: + - cosmos-sdk release/v0.50.x + - cosmos-sdk release/v0.52.x +- Outputs: + - Workflow artifacts + - Container image + +### Workflow #2 - Test Cosmos-SDK / Comet +- Application: SimAp from `cosmos/cosmos-sdk` +- Dependencies: + - cosmos-sdk HEAD/main + - cometbft HEAD/main + +### Workflow #3 - Release Cosmos-SDK / IBC +- Application: SimApp from `cosmos/ibc-go` +- Dependencies: + - cosmos-sdk release/v0.50.x + - cosmos-sdk modules forced on release/v0.50.x