From 2d1759f850b60b37e43ac9e59bc57b84bd55601d Mon Sep 17 00:00:00 2001 From: chrisli30 Date: Fri, 4 Apr 2025 23:14:14 -0700 Subject: [PATCH 1/9] Re-organize workflows and releasing process --- .../publish-dev-docker-on-staging.yml | 13 +- .../workflows/release-and-update-docker.yml | 143 ++++++++++++++++++ .../{test.yml => run-test-on-pr.yml} | 26 +++- .github/workflows/update-docker-dev.yml | 56 +++++++ .github/workflows/update-docker-mainnet.yml | 59 ++++++++ RELEASE.md | 63 ++++++++ config/aggregator.yaml_sepolia | 35 +++++ config/operator.yaml_sepolia | 51 +++++++ 8 files changed, 436 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/release-and-update-docker.yml rename .github/workflows/{test.yml => run-test-on-pr.yml} (64%) create mode 100644 .github/workflows/update-docker-dev.yml create mode 100644 .github/workflows/update-docker-mainnet.yml create mode 100644 RELEASE.md create mode 100644 config/aggregator.yaml_sepolia create mode 100644 config/operator.yaml_sepolia diff --git a/.github/workflows/publish-dev-docker-on-staging.yml b/.github/workflows/publish-dev-docker-on-staging.yml index 37552030..368cd47f 100644 --- a/.github/workflows/publish-dev-docker-on-staging.yml +++ b/.github/workflows/publish-dev-docker-on-staging.yml @@ -12,8 +12,8 @@ on: workflow_dispatch: jobs: - publish-dev-build: - name: Publish dev build docker image to dockerhub + publish-staging-build: + name: Publish staging build docker image to dockerhub runs-on: 'ubuntu-latest' steps: - name: Login to Docker Hub @@ -35,22 +35,19 @@ jobs: id: meta uses: docker/metadata-action@v5 with: - # This is a dedicated repository to house the development/preview build images: | avaprotocol/avs-dev tags: | - type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }} + type=raw,value=staging type=raw,value={{sha}} type=ref,event=branch type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - - name: Build and push avs-dev docker image + - name: Build and push staging docker image uses: docker/build-push-action@v6 with: build-args: | - RELEASE_TAG=${{ inputs.tag || github.sha || github.head_ref || github.ref_name }} + RELEASE_TAG=staging-${{ github.sha }} COMMIT_SHA=${{ github.sha }} platforms: linux/amd64,linux/arm64 context: . diff --git a/.github/workflows/release-and-update-docker.yml b/.github/workflows/release-and-update-docker.yml new file mode 100644 index 00000000..b1bc86de --- /dev/null +++ b/.github/workflows/release-and-update-docker.yml @@ -0,0 +1,143 @@ +name: Auto Release on Main + +on: + push: + branches: + - main + +jobs: + release: + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + steps: + - name: Checkout repository with full history + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Required for go-semantic-release + + - name: Setup Go environment + uses: actions/setup-go@v4 + with: + go-version: '1.22' + + - name: Run Go linter + uses: golangci/golangci-lint-action@v3 + with: + version: latest + + - name: Run Go tests + run: go test -v ./... + + - name: Generate commit summary + id: git-summary + run: | + echo "## Summary" >> commit-summary.md + echo "" >> commit-summary.md + # Count different types of changes + FEATURES=$(git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"%s" --no-merges | grep -i "^feat" | wc -l) + FIXES=$(git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"%s" --no-merges | grep -i "^fix" | wc -l) + DOCS=$(git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"%s" --no-merges | grep -i "^docs" | wc -l) + echo "* $FEATURES new features" >> commit-summary.md + echo "* $FIXES bug fixes" >> commit-summary.md + echo "* $DOCS documentation updates" >> commit-summary.md + echo "" >> commit-summary.md + echo "## Changes since last release" >> commit-summary.md + echo "" >> commit-summary.md + git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"* %s (%h)" --no-merges >> commit-summary.md + echo "COMMIT_SUMMARY<> $GITHUB_ENV + cat commit-summary.md >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + + - name: Run semantic versioning and release + id: semantic-release + uses: go-semantic-release/action@v1 + with: + hooks: goreleaser + changelog: ${{ env.COMMIT_SUMMARY }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + avaprotocol/ap-avs + tags: | + type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }} + type=raw,value={{sha}},enable=${{ github.ref == format('refs/heads/{0}', 'main') }} + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + + - name: Build and push Docker image + if: steps.semantic-release.outputs.new_release_published == 'true' + uses: docker/build-push-action@v6 + with: + build-args: | + RELEASE_TAG=${{ steps.semantic-release.outputs.new_version }} + platforms: linux/amd64,linux/arm64 + context: . + file: dockerfiles/operator.Dockerfile + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + deploy: + needs: release + if: needs.release.outputs.new_release_published == 'true' + runs-on: ubuntu-latest + permissions: + actions: write + strategy: + matrix: + workflow: + - id: 'deploy-sepolia.yml' + name: 'Sepolia' + environment: 'Sepolia' + directory: 'sepolia' + - id: 'deploy-base-sepolia.yml' + name: 'Base Sepolia' + environment: 'Base Sepolia' + directory: 'base-sepolia' + - id: 'deploy-base.yml' + name: 'Base' + environment: 'Base' + directory: 'base' + - id: 'deploy-ethereum.yml' + name: 'Ethereum' + environment: 'Ethereum' + directory: 'ethereum' + steps: + - name: Trigger ${{ matrix.workflow.name }} deployment + uses: actions/github-script@v7 + with: + script: | + github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: '${{ matrix.workflow.id }}', + ref: 'main', + inputs: { + tag: '${{ needs.release.outputs.new_version }}', + environment: '${{ matrix.workflow.environment }}', + directory: '${{ matrix.workflow.directory }}' + } + }) \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/run-test-on-pr.yml similarity index 64% rename from .github/workflows/test.yml rename to .github/workflows/run-test-on-pr.yml index 0e69c777..94ca643b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/run-test-on-pr.yml @@ -1,8 +1,29 @@ -name: Run Tests +name: Run Tests on PR or on-demand on: - push: + pull_request: + # Only run tests when PR to staging of main and these files are changed + branches: + - main + - staging + paths: + - "**.go" + - "go.mod" + - "go.sum" + - "core/**" + - "pkg/**" + - "aggregator/**" + - "operator/**" + - "model/**" + - "cmd/**" + - "version/**" + - "config/**" workflow_dispatch: + inputs: + branch: + description: "Branch to run tests against" + required: true + type: string jobs: test: @@ -28,6 +49,7 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive + ref: ${{ github.event.inputs.branch || github.ref }} - name: Run Go test env: diff --git a/.github/workflows/update-docker-dev.yml b/.github/workflows/update-docker-dev.yml new file mode 100644 index 00000000..425592d8 --- /dev/null +++ b/.github/workflows/update-docker-dev.yml @@ -0,0 +1,56 @@ +name: Build and Publish Docker from Dev Branch + +on: + workflow_dispatch: + inputs: + branch: + description: 'Branch to build from' + required: true + type: string + +jobs: + publish-dev-build: + name: Publish dev build docker image to dockerhub + runs-on: 'ubuntu-latest' + steps: + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Checkout repository code + uses: actions/checkout@v4 + with: + ref: ${{ inputs.branch }} + + - name: Configure QEMU for multi-architecture builds + uses: docker/setup-qemu-action@v3 + + - name: Configure Docker Buildx for multi-architecture builds + uses: docker/setup-buildx-action@v3 + + - name: Generate Docker image metadata and tags + id: meta + uses: docker/metadata-action@v5 + with: + images: | + avaprotocol/avs-dev + tags: | + type=raw,value=development + type=raw,value={{sha}} + type=ref,event=branch + type=ref,event=pr + + - name: Build and push ap-avs-dev docker image + uses: docker/build-push-action@v6 + with: + build-args: | + RELEASE_TAG=${{ github.sha }} + COMMIT_SHA=${{ github.sha }} + platforms: linux/amd64,linux/arm64 + context: . + file: dockerfiles/operator.Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/update-docker-mainnet.yml b/.github/workflows/update-docker-mainnet.yml new file mode 100644 index 00000000..9dfa0ab1 --- /dev/null +++ b/.github/workflows/update-docker-mainnet.yml @@ -0,0 +1,59 @@ +name: Update Mainnet Docker Image +# This workflow is specifically designed to merge from main to mainnet +# and publish the Docker image with the mainnet tag. + +# Due to EigenSDK package differences on Ethereum mainnet, +# this workflow ensures the mainnet branch stays in sync with main +# while maintaining its own Docker image tag. + +on: + workflow_dispatch: + +jobs: + update-mainnet: + name: Update mainnet branch and publish Docker image + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + steps: + - name: Checkout repository with full history + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Configure Git + run: | + git config user.name "GitHub Actions" + git config user.email "github-actions@github.com" + + - name: Merge main into mainnet + run: | + git checkout mainnet + git merge main --no-ff -m "Merge main into mainnet" + git push origin mainnet + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Configure QEMU for multi-architecture builds + uses: docker/setup-qemu-action@v3 + + - name: Configure Docker Buildx for multi-architecture builds + uses: docker/setup-buildx-action@v3 + + - name: Build and push mainnet Docker image + uses: docker/build-push-action@v6 + with: + context: . + file: dockerfiles/operator.Dockerfile + push: true + tags: | + avaprotocol/ap-avs:mainnet + build-args: | + RELEASE_TAG=mainnet-${{ github.sha }} + COMMIT_SHA=${{ github.sha }} + platforms: linux/amd64,linux/arm64 diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 00000000..b6aeeab8 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,63 @@ +# AP-AVS Release Process + +## Overview + +The release process follows a staged approach from development to production, with specific Docker image management for each stage. + +## Branch and Docker Image Alignment + +| Environment | Github Branch | Docker Image Repository | Docker Tag Format | Managed By | Trigger Condition | +| ----------- | ------------- | ---------------------------- | -------------------------- | ------------------------------- | --------------------------------------------------------------------------------- | +| Development | `dev` | `avaprotocol/ap-avs-dev` | `commit-hash` | GA: `update-docker-dev` | Manual trigger against dev branch | +| Staging | `staging` | `avaprotocol/ap-avs-staging` | `commit-hash` | GA: `update-docker-staging` | Automatic on PR merge to staging branch | +| Production | `main` | `avaprotocol/ap-avs` | `x.y.z` (semantic version) | GA: `release-and-update-docker` | Automatic on PR merge from staging to main | +| Mainnet | `mainnet` | `avaprotocol/ap-avs` | `mainnet` | GA: `update-docker-mainnet` | Manual trigger to sync main to mainnet and deploy | + +### Important Notes + +Due to the EigenSDK package difference on Ethereum mainnet, the implementation of the EigenSDK on `mainnet` branched out from `main`. For updating the `avaprotocol/ap-avs@mainnet` docker, the `update-docker-mainnet` GA perform the below actions. + +1. Merge the working code from `main` to `mainnet` +2. Build Docker image from `mainnet` +3. Publish the docker to the `avaprotocol/ap-avs@mainnet` tag. + +## Versioning and Releasing + +The versioning process is automated and triggered when code is merged from `staging` to `main` through a pull request. The `release-on-pr` GitHub Action handles this process using `go-semantic-release`. + +### Commit Message Format + +For versioning to work correctly, commit messages must follow the conventional commit format: + +- `feat:` for new features (minor version bump) +- `fix:` for bug fixes (patch version bump) +- `docs:` for documentation changes (no version bump) +- `BREAKING CHANGE:` or `feat!:` for breaking changes (major version bump) + +### Release Process + +When a PR from `staging` to `main` is merged, the following happens automatically: + +1. Version Determination: + + - Analyzes commit messages since the last release + - Determines the next version number based on commit types + - Major version for breaking changes + - Minor version for new features + - Patch version for bug fixes + +2. Release Creation: + + - Creates a GitHub Release with the new version + - Builds and publishes Docker image to `avaprotocol/ap-avs` with version tag + - Does NOT create Git tags automatically + +3. Deployment: + - Triggers deployments to all environments, currently `Sepolia`, `Base Sepolia`, `Ethereum` and `Base`. + - Each environment uses the same version and docker image, but vary on `environment` and `directory`. + +### Important Notes + +- Docker images are tagged with the version number such as `x.y.z` +- The `latest` tag of Docker image is not automatically updated +- Git tags need to be created manually if needed \ No newline at end of file diff --git a/config/aggregator.yaml_sepolia b/config/aggregator.yaml_sepolia new file mode 100644 index 00000000..1fb37574 --- /dev/null +++ b/config/aggregator.yaml_sepolia @@ -0,0 +1,35 @@ +ecdsa_private_key: f6dc500a34373d7e8af2a4b0b2635253ce1bd92077ed86c24393fb01298abc1d + +eth_rpc_url: https://holesky.gateway.tenderly.co/6PJfDJkrMGBl3f4MuyU5M +eth_ws_url: wss://holesky.gateway.tenderly.co/6PJfDJkrMGBl3f4MuyU5M + +rpc_bind_address: "0.0.0.0:2206" +http_bind_address: "0.0.0.0:8080" + +avs_registry_coordinator_address: 0x90c6d6f2A78d5Ce22AB8631Ddb142C03AC87De7a +operator_state_retriever_address: 0xb7bb920538e038DFFEfcB55caBf713652ED2031F + +etherscan_url: https://etherscan.io +eigenlayer_url: https://app.eigenlayer.xyz + +environment: development +db_path: /tmp/ap-avs/db + +jwt_secret: 1b7db1c64236d92de3b3ed32e5d6bf56 + +# account abstraction config +# Sepolia +smart_wallet: + eth_rpc_url: https://ethereum-sepolia.core.chainstack.com/2504cb0765f0edf6c33d99095148006f + eth_ws_url: wss://ethereum-sepolia.core.chainstack.com/2504cb0765f0edf6c33d99095148006f + bundler_url: https://bundler-sepolia.avaprotocol.org/?apikey=kt8qTj8MtmAQGsj17Urz1aMATV1ySn4R + factory_address: 0x29adA1b5217242DEaBB142BC3b1bCfFdd56008e7 + entrypoint_address: 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 + + # master key to generate and sign userops for any wallet + # wallet: 0xafDe18682A3ee10E4FA2DDE582CdAd24b939C36F + controller_private_key: fa8f65b36c4b312aa4950e475f314c34d273ec3d841a765843926fd00e314563 + +macros: + secrets: + ap_notify_bot_token: "7771086042:AAG7UvbAyN8_8OrS-MjRfwz8WpWDKf4Yw8U" # Telegram bot token for notifications diff --git a/config/operator.yaml_sepolia b/config/operator.yaml_sepolia new file mode 100644 index 00000000..64d89f8c --- /dev/null +++ b/config/operator.yaml_sepolia @@ -0,0 +1,51 @@ +# this sets the logger level (true = info, false = debug) +production: false + +operator_address: 0x997E5D40a32c44a3D93E59fC55C4Fd20b7d2d49D + +avs_registry_coordinator_address: 0x90c6d6f2A78d5Ce22AB8631Ddb142C03AC87De7a +operator_state_retriever_address: 0xb7bb920538e038DFFEfcB55caBf713652ED2031F + +eth_rpc_url: https://ethereum-holesky-rpc.publicnode.com +eth_ws_url: wss://eth-holesky.g.alchemy.com/v2/A1UDofV6tMUsH4dvA4mmUCtQp_oPX7lL + +# If you running this using eigenlayer CLI and the provided AVS packaging structure, +# this should be /operator_keys/ecdsa_key.json as the host path will be asked while running +# +# If you are running locally using go run main.go, this should be full path to your local ecdsa key file +ecdsa_private_key_store_path: /Users/mikasa/Code/EigenLayer-AVS/keys/vinh.ecdsa.key.json +#ecdsa_private_key_store_path: alias-ecdsa.key.json + +# If you running this using eigenlayer CLI and the provided AVS packaging structure, +# this should be /operator_keys/bls_key.json as the host path will be asked while running +# +# We are using bn254 curve for bls keys +# +# If you are running locally using go run main.go, this should be full path to your local bls key file +bls_private_key_store_path: /Users/mikasa/Code/EigenLayer-AVS/keys/vinh.bls.key.json + +# When setting remote signer, we can skip bls_private_key_store_path +# bls_remote_signer: +# grpc_url: "127.0.0.1:50051" +# public_key: "a2e8430e4c3932f33260b4346ab9845ce6192c5ca6472f3a481eaaa02d066d0a" +# password: "c4a7c49604164fe9cb10e6fc52afdca7f39a" + +# address which the aggregator listens on for operator signed messages +aggregator_server_ip_port_address: + "127.0.0.1:2206" + #aggregator_server_ip_port_address: "aggregator-holesky.avaprotocol.org:2206" + +# avs node spec compliance https://eigen.nethermind.io/docs/spec/intro +eigen_metrics_ip_port_address: localhost:9090 +enable_metrics: true +node_api_ip_port_address: localhost:9010 +enable_node_api: true + +db_path: /tmp/ap-avs-operator + +# Destination chain +target_chain: + eth_rpc_url: https://ethereum-sepolia.core.chainstack.com/2504cb0765f0edf6c33d99095148006f + eth_ws_url: wss://ethereum-sepolia.core.chainstack.com/2504cb0765f0edf6c33d99095148006f + #eth_rpc_url: https://api-soneium-minato.dwellir.com/b656fef0-86c1-4020-adbd-dc01efa33fb0 + #eth_ws_url: wss://api-soneium-minato.dwellir.com/b656fef0-86c1-4020-adbd-dc01efa33fb0 From 8b752d92d0a55b6ae851a71aaabb7d53d93ea617 Mon Sep 17 00:00:00 2001 From: chrisli30 Date: Fri, 4 Apr 2025 23:34:00 -0700 Subject: [PATCH 2/9] Added Environment details to Release.md --- RELEASE.md | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index b6aeeab8..fc630a23 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -6,12 +6,33 @@ The release process follows a staged approach from development to production, wi ## Branch and Docker Image Alignment -| Environment | Github Branch | Docker Image Repository | Docker Tag Format | Managed By | Trigger Condition | -| ----------- | ------------- | ---------------------------- | -------------------------- | ------------------------------- | --------------------------------------------------------------------------------- | -| Development | `dev` | `avaprotocol/ap-avs-dev` | `commit-hash` | GA: `update-docker-dev` | Manual trigger against dev branch | -| Staging | `staging` | `avaprotocol/ap-avs-staging` | `commit-hash` | GA: `update-docker-staging` | Automatic on PR merge to staging branch | -| Production | `main` | `avaprotocol/ap-avs` | `x.y.z` (semantic version) | GA: `release-and-update-docker` | Automatic on PR merge from staging to main | -| Mainnet | `mainnet` | `avaprotocol/ap-avs` | `mainnet` | GA: `update-docker-mainnet` | Manual trigger to sync main to mainnet and deploy | +| Environment | Github Branch | Docker Image Repository | Docker Tag Format | Managed By | Trigger Condition | +| ----------- | ------------- | ---------------------------- | -------------------------- | ------------------------------- | ------------------------------------------------- | +| Development | `dev` | `avaprotocol/ap-avs-dev` | `commit-hash` | GA: `update-docker-dev` | Manual trigger against dev branch | +| Staging | `staging` | `avaprotocol/ap-avs-staging` | `commit-hash` | GA: `update-docker-staging` | Automatic on PR merge to staging branch | +| Production | `main` | `avaprotocol/ap-avs` | `x.y.z` (semantic version) | GA: `release-and-update-docker` | Automatic on PR merge from staging to main | +| Mainnet | `mainnet` | `avaprotocol/ap-avs` | `mainnet` | GA: `update-docker-mainnet` | Manual trigger to sync main to mainnet and deploy | + +### Environment Details + +- **Staging Branch**: + + - This branch serves as a caching and testing pool before changes are merged into main + - The staging Docker image is updated after each PR merge from dev branches. + - Changes in staging are considered pre-production and not yet live + +- **Main Branch**: + + - Docker images are automatically built and published after merging into main + - Creates a GitHub Release with the semantic versioning (x.y.z) and for image tags + - Deploys to all environments (Ethereum, Base, etc.). Each environment uses the same version but different configurations + +- **Mainnet Branch**: + - Uses non-fast-forward merge to preserve mainnet-specific changes (different EigenSDK version) + - After testing the Docker image on test environments, we run `update-docker-mainnet` to officially update the `avaprotocol/ap-avs@mainnet` tag + - Operators automatically download and upgrade their images when the mainnet tag is updated + - Requires manual trigger for deployment + ### Important Notes @@ -60,4 +81,4 @@ When a PR from `staging` to `main` is merged, the following happens automaticall - Docker images are tagged with the version number such as `x.y.z` - The `latest` tag of Docker image is not automatically updated -- Git tags need to be created manually if needed \ No newline at end of file +- Git tags need to be created manually if needed From 2b775d18194a304f142097dbfc136f9e08174877 Mon Sep 17 00:00:00 2001 From: chrisli30 Date: Fri, 9 May 2025 16:29:41 -0700 Subject: [PATCH 3/9] Added commit message naming convension --- .pre-commit-config.yaml | 43 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b6b77126..6c838a19 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,24 +7,61 @@ repos: language: system types: [go] pass_filenames: false - + - id: go-mod-tidy name: go mod tidy entry: go mod tidy language: system types: [go] pass_filenames: false - + - id: go-vet name: go vet entry: go vet ./... language: system types: [go] pass_filenames: false - + - id: golangci-lint name: golangci-lint entry: golangci-lint run language: system types: [go] pass_filenames: false + + - id: conventional-commit-check + name: Conventional Commit Message Check + entry: |- + bash -c ' + COMMIT_MSG_FILE="$1" + FIRST_LINE=$(head -n1 "$COMMIT_MSG_FILE") + # Regex for conventional commit: type(optional_scope)!: subject + # Allowed types: feat, fix, docs, style, refactor, perf, test, chore, ci, build, revert + # Allows an optional scope in parentheses e.g. feat(parser): + # Allows an optional ! for breaking change e.g. feat!: + # Requires a colon and a space after type/scope/!. + # Requires some subject text. + PATTERN="^(feat|fix|docs|style|refactor|perf|test|chore|ci|build|revert)(\([\w\s-]+\))?!?:\[[:space:]].+" + if ! grep -Eq "$PATTERN" <<< "$FIRST_LINE"; then + echo "-------------------------------------------------------------------" + echo "ERROR: Commit message does not follow Conventional Commits format." + echo "-------------------------------------------------------------------" + echo "It must start with a type like feat, fix, docs, etc.," + echo "followed by an optional scope in parentheses (e.g. (api), (ui))," + echo "an optional exclamation mark for breaking changes (!)," + echo "a colon and a single space, and then the subject." + echo "" + echo "Examples:" + echo " feat: add new user authentication feature" + echo " fix(parser): correctly handle empty input" + echo " docs!: update API documentation for breaking change" + echo "" + echo "Allowed types: feat, fix, docs, style, refactor, perf, test, chore, ci, build, revert" + echo "For more details, see: https://www.conventionalcommits.org/" + echo "-------------------------------------------------------------------" + exit 1 + fi + ' + language: system + stages: [commit-msg] + pass_filenames: true # The script expects the filename as $1 From 3d925d45f950823e4b5ee52924e385942d766dfa Mon Sep 17 00:00:00 2001 From: chrisli30 Date: Fri, 9 May 2025 16:30:03 -0700 Subject: [PATCH 4/9] Change to publish dev docker on PR close --- .../publish-dev-docker-on-staging.yml | 28 ++++++++- .github/workflows/update-docker-dev.yml | 56 ------------------ .github/workflows/update-docker-mainnet.yml | 59 ------------------- 3 files changed, 26 insertions(+), 117 deletions(-) delete mode 100644 .github/workflows/update-docker-dev.yml delete mode 100644 .github/workflows/update-docker-mainnet.yml diff --git a/.github/workflows/publish-dev-docker-on-staging.yml b/.github/workflows/publish-dev-docker-on-staging.yml index 368cd47f..8420395f 100644 --- a/.github/workflows/publish-dev-docker-on-staging.yml +++ b/.github/workflows/publish-dev-docker-on-staging.yml @@ -1,7 +1,8 @@ name: Publish Dev Docker image upon staging change on: - push: + pull_request: + types: [closed] branches: - staging paths: @@ -13,6 +14,7 @@ on: jobs: publish-staging-build: + if: github.event.pull_request.merged == true name: Publish staging build docker image to dockerhub runs-on: 'ubuntu-latest' steps: @@ -24,6 +26,28 @@ jobs: - name: Checkout uses: actions/checkout@v4 + with: + fetch-depth: 0 # Ensure fetch-depth is 0 for git log + + - name: Determine Tag Prefix from Source Branch + id: vars + run: | + RAW_BRANCH_NAME="${{ github.event.pull_request.head.ref }}" # Get source branch directly + TAG_PREFIX="" + + if [[ -n "$RAW_BRANCH_NAME" ]]; then + # Sanitize the branch name for use in a Docker tag: + # 1. Replace '/' with '-' + # 2. Keep only alphanumeric characters, '.', and '-' + # 3. Replace sequences of invalid characters with a single '-' + # 4. Remove leading/trailing '-' + SANITIZED_NAME=$(echo "$RAW_BRANCH_NAME" | sed 's|/|-|g' | tr -cs 'a-zA-Z0-9.-' '-' | sed 's/--\\+/-/g' | sed 's/^-*//;s/-*$//') + if [[ -n "$SANITIZED_NAME" ]]; then + TAG_PREFIX="$SANITIZED_NAME" + fi + fi + echo "TAG_PREFIX=${TAG_PREFIX}" >> $GITHUB_OUTPUT + shell: bash - name: Set up QEMU uses: docker/setup-qemu-action@v3 @@ -47,7 +71,7 @@ jobs: uses: docker/build-push-action@v6 with: build-args: | - RELEASE_TAG=staging-${{ github.sha }} + RELEASE_TAG=${{ steps.vars.outputs.TAG_PREFIX }}${{ steps.vars.outputs.TAG_PREFIX:+'-' }}${{ github.sha }} COMMIT_SHA=${{ github.sha }} platforms: linux/amd64,linux/arm64 context: . diff --git a/.github/workflows/update-docker-dev.yml b/.github/workflows/update-docker-dev.yml deleted file mode 100644 index 425592d8..00000000 --- a/.github/workflows/update-docker-dev.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Build and Publish Docker from Dev Branch - -on: - workflow_dispatch: - inputs: - branch: - description: 'Branch to build from' - required: true - type: string - -jobs: - publish-dev-build: - name: Publish dev build docker image to dockerhub - runs-on: 'ubuntu-latest' - steps: - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Checkout repository code - uses: actions/checkout@v4 - with: - ref: ${{ inputs.branch }} - - - name: Configure QEMU for multi-architecture builds - uses: docker/setup-qemu-action@v3 - - - name: Configure Docker Buildx for multi-architecture builds - uses: docker/setup-buildx-action@v3 - - - name: Generate Docker image metadata and tags - id: meta - uses: docker/metadata-action@v5 - with: - images: | - avaprotocol/avs-dev - tags: | - type=raw,value=development - type=raw,value={{sha}} - type=ref,event=branch - type=ref,event=pr - - - name: Build and push ap-avs-dev docker image - uses: docker/build-push-action@v6 - with: - build-args: | - RELEASE_TAG=${{ github.sha }} - COMMIT_SHA=${{ github.sha }} - platforms: linux/amd64,linux/arm64 - context: . - file: dockerfiles/operator.Dockerfile - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/update-docker-mainnet.yml b/.github/workflows/update-docker-mainnet.yml deleted file mode 100644 index 9dfa0ab1..00000000 --- a/.github/workflows/update-docker-mainnet.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: Update Mainnet Docker Image -# This workflow is specifically designed to merge from main to mainnet -# and publish the Docker image with the mainnet tag. - -# Due to EigenSDK package differences on Ethereum mainnet, -# this workflow ensures the mainnet branch stays in sync with main -# while maintaining its own Docker image tag. - -on: - workflow_dispatch: - -jobs: - update-mainnet: - name: Update mainnet branch and publish Docker image - runs-on: ubuntu-latest - permissions: - contents: write - packages: write - steps: - - name: Checkout repository with full history - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Configure Git - run: | - git config user.name "GitHub Actions" - git config user.email "github-actions@github.com" - - - name: Merge main into mainnet - run: | - git checkout mainnet - git merge main --no-ff -m "Merge main into mainnet" - git push origin mainnet - - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Configure QEMU for multi-architecture builds - uses: docker/setup-qemu-action@v3 - - - name: Configure Docker Buildx for multi-architecture builds - uses: docker/setup-buildx-action@v3 - - - name: Build and push mainnet Docker image - uses: docker/build-push-action@v6 - with: - context: . - file: dockerfiles/operator.Dockerfile - push: true - tags: | - avaprotocol/ap-avs:mainnet - build-args: | - RELEASE_TAG=mainnet-${{ github.sha }} - COMMIT_SHA=${{ github.sha }} - platforms: linux/amd64,linux/arm64 From 23d9bc7890f6bdb348ba79aa3d70cf06ae96e474 Mon Sep 17 00:00:00 2001 From: chrisli30 Date: Fri, 9 May 2025 16:53:51 -0700 Subject: [PATCH 5/9] Change to publish dev docker on PR close --- .github/workflows/deploy-avs.yml | 59 ++++++++ .github/workflows/deploy-base-sepolia.yml | 21 +++ .github/workflows/deploy-base.yml | 17 +++ .../publish-dev-docker-on-staging.yml | 8 +- .../release-and-update-docker-on-main.yml | 140 +++++++++++++++++ .../workflows/release-and-update-docker.yml | 143 ------------------ 6 files changed, 240 insertions(+), 148 deletions(-) create mode 100644 .github/workflows/deploy-avs.yml create mode 100644 .github/workflows/deploy-base-sepolia.yml create mode 100644 .github/workflows/deploy-base.yml create mode 100644 .github/workflows/release-and-update-docker-on-main.yml delete mode 100644 .github/workflows/release-and-update-docker.yml diff --git a/.github/workflows/deploy-avs.yml b/.github/workflows/deploy-avs.yml new file mode 100644 index 00000000..a54fa7fd --- /dev/null +++ b/.github/workflows/deploy-avs.yml @@ -0,0 +1,59 @@ +name: Reusable Aggregator Deploy + +on: + workflow_call: + inputs: + environment: + required: true + type: string + directory: + required: true + type: string + secrets: + AVS_SSH_KEY: + required: true + AVS_SERVER_HOST: + required: true + +jobs: + aggregator: + runs-on: ubuntu-latest + environment: + name: ${{ inputs.environment }} + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: SSH and Deploy + uses: appleboy/ssh-action@v0.1.5 + with: + host: ${{ secrets.AVS_SERVER_HOST }} + username: ava + key: ${{ secrets.AVS_SSH_KEY }} + script: | + echo "Deploying to environment: ${{ inputs.environment }}" + cd $HOME/ap-aggregator-setup/${{ inputs.directory }} + docker compose pull + docker compose up -d --force-recreate + + operator: + runs-on: ubuntu-latest + environment: + name: ${{ inputs.environment }} + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: SSH and Deploy + uses: appleboy/ssh-action@v0.1.5 + with: + host: ${{ secrets.AVS_SERVER_HOST }} + username: ava + key: ${{ secrets.AVS_SSH_KEY }} + script: | + echo "Deploying to environment: ${{ inputs.environment }}" + cd $HOME/ap-operator-setup/${{ inputs.directory == 'sepolia' && 'holesky' || inputs.directory }} + docker compose pull + docker compose up -d --force-recreate diff --git a/.github/workflows/deploy-base-sepolia.yml b/.github/workflows/deploy-base-sepolia.yml new file mode 100644 index 00000000..1e2d5dfb --- /dev/null +++ b/.github/workflows/deploy-base-sepolia.yml @@ -0,0 +1,21 @@ +name: Deploy to Base Sepolia + +on: + workflow_run: + workflows: ["Publish dev build docker image to dockerhub"] + types: + - completed + branches: + - main + workflow_dispatch: + +jobs: + deploy-avs: + #if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.name == 'Push' }} + uses: ./.github/workflows/deploy-avs.yml + with: + environment: "Base Sepolia" + directory: "base-sepolia" + secrets: + AVS_SSH_KEY: ${{ secrets.AVS_SSH_KEY }} + AVS_SERVER_HOST: ${{ secrets.AVS_SERVER_HOST }} \ No newline at end of file diff --git a/.github/workflows/deploy-base.yml b/.github/workflows/deploy-base.yml new file mode 100644 index 00000000..02c66d2d --- /dev/null +++ b/.github/workflows/deploy-base.yml @@ -0,0 +1,17 @@ +name: Deploy to Base + +on: + push: + tags: + - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 + workflow_dispatch: + +jobs: + deploy-avs: + uses: ./.github/workflows/deploy-avs.yml + with: + environment: Base + directory: base + secrets: + AVS_SSH_KEY: ${{ secrets.AVS_SSH_KEY }} + AVS_SERVER_HOST: ${{ secrets.AVS_SERVER_HOST }} \ No newline at end of file diff --git a/.github/workflows/publish-dev-docker-on-staging.yml b/.github/workflows/publish-dev-docker-on-staging.yml index 8420395f..f659bb00 100644 --- a/.github/workflows/publish-dev-docker-on-staging.yml +++ b/.github/workflows/publish-dev-docker-on-staging.yml @@ -62,10 +62,8 @@ jobs: images: | avaprotocol/avs-dev tags: | - type=raw,value=staging - type=raw,value={{sha}} - type=ref,event=branch - type=ref,event=pr + type=pr # Generates pr-123 from the PR number + type=raw,value={{sha}} # Full commit SHA - name: Build and push staging docker image uses: docker/build-push-action@v6 @@ -76,6 +74,6 @@ jobs: platforms: linux/amd64,linux/arm64 context: . file: dockerfiles/operator.Dockerfile - push: ${{ github.event_name != 'pull_request' }} + push: true # Always push when this job runs (merged PR to staging) tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/.github/workflows/release-and-update-docker-on-main.yml b/.github/workflows/release-and-update-docker-on-main.yml new file mode 100644 index 00000000..3b3f9829 --- /dev/null +++ b/.github/workflows/release-and-update-docker-on-main.yml @@ -0,0 +1,140 @@ +name: Build and Publish PR Pre-release Docker + +on: + pull_request: + types: + - opened + - synchronize + branches: + - main + +jobs: + build-and-publish-pr-docker: + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + steps: + - name: Checkout repository with full history + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Required for go-semantic-release + + - name: Setup Go environment + uses: actions/setup-go@v4 + with: + go-version: '1.22' + + - name: Run Go linter + uses: golangci/golangci-lint-action@v3 + with: + version: latest + + - name: Run Go tests + run: go test -v ./... + + - name: Generate commit summary + id: git-summary + run: | + echo "## Summary" >> commit-summary.md + echo "" >> commit-summary.md + FEATURES=$(git log $(git describe --tags --abbrev=0 2>/dev/null || git rev-list --max-parents=0 HEAD)..HEAD --pretty=format:"%s" --no-merges | grep -i "^feat" | wc -l) + FIXES=$(git log $(git describe --tags --abbrev=0 2>/dev/null || git rev-list --max-parents=0 HEAD)..HEAD --pretty=format:"%s" --no-merges | grep -i "^fix" | wc -l) + DOCS=$(git log $(git describe --tags --abbrev=0 2>/dev/null || git rev-list --max-parents=0 HEAD)..HEAD --pretty=format:"%s" --no-merges | grep -i "^docs" | wc -l) + echo "* $FEATURES new features" >> commit-summary.md + echo "* $FIXES bug fixes" >> commit-summary.md + echo "* $DOCS documentation updates" >> commit-summary.md + echo "" >> commit-summary.md + echo "## Changes since last release" >> commit-summary.md + echo "" >> commit-summary.md + git log $(git describe --tags --abbrev=0 2>/dev/null || git rev-list --max-parents=0 HEAD)..HEAD --pretty=format:"* %s (%h)" --no-merges >> commit-summary.md + echo "COMMIT_SUMMARY<> $GITHUB_ENV + cat commit-summary.md >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + + - name: Run semantic versioning and create pre-release + id: semantic-release + uses: go-semantic-release/action@v1 + with: + hooks: goreleaser + changelog: ${{ env.COMMIT_SUMMARY }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Format Pre-release Version for Docker Tag + id: formatted-version + if: steps.semantic-release.outputs.new_release_published == 'true' + run: | + SEMREL_VERSION="${{ steps.semantic-release.outputs.new_version }}" + # Extract base version (e.g., v1.2.3) + BASE_VERSION=$(echo "$SEMREL_VERSION" | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+') + # Extract the part after the base version and the first hyphen (the pre-release suffix) + ORIGINAL_SUFFIX=$(echo "$SEMREL_VERSION" | sed -E "s/^${BASE_VERSION}-?(.*)$/\1/") + + if [[ -z "$BASE_VERSION" ]]; then # Should not happen with semantic versions + echo "Error: Could not parse base version from $SEMREL_VERSION" + exit 1 + fi + + if [[ -z "$ORIGINAL_SUFFIX" ]]; then # Not a pre-release, or unexpected format + # This case should ideally not occur for a PR pre-release workflow. + # Defaulting to base version with -rc.0 if suffix is missing. + FINAL_DOCKER_TAG="${BASE_VERSION}-rc.0" + elif [[ "$ORIGINAL_SUFFIX" == rc\.* ]]; then + # Already in the desired rc.N format (e.g., rc.1, rc.10) + FINAL_DOCKER_TAG="$SEMREL_VERSION" + else + # Extract trailing digits from the original suffix for the increment + INCREMENT=$(echo "$ORIGINAL_SUFFIX" | grep -oE '[0-9]+$' || echo "0") + FINAL_DOCKER_TAG="${BASE_VERSION}-rc.${INCREMENT}" + fi + echo "Original semantic-release version: $SEMREL_VERSION" + echo "Formatted Docker tag: $FINAL_DOCKER_TAG" + echo "docker_tag=${FINAL_DOCKER_TAG}" >> "$GITHUB_OUTPUT" + shell: bash + + - name: Print Formatted Docker Tag (Debug) + if: steps.semantic-release.outputs.new_release_published == 'true' + run: | + echo "The formatted Docker tag that will be used is: ${{ steps.formatted-version.outputs.docker_tag }}" + + - name: Login to Docker Hub + if: steps.semantic-release.outputs.new_release_published == 'true' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up QEMU + if: steps.semantic-release.outputs.new_release_published == 'true' + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + if: steps.semantic-release.outputs.new_release_published == 'true' + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + if: steps.semantic-release.outputs.new_release_published == 'true' + uses: docker/metadata-action@v5 + with: + images: | + avaprotocol/ap-avs + tags: | + # Only tag with the formatted pre-release version number + type=raw,value=${{ steps.formatted-version.outputs.docker_tag }} + + - name: Build and push Docker image + if: steps.semantic-release.outputs.new_release_published == 'true' + uses: docker/build-push-action@v6 + with: + build-args: | + RELEASE_TAG=${{ steps.semantic-release.outputs.new_version }} + platforms: linux/amd64,linux/arm64 + context: . + file: dockerfiles/operator.Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/.github/workflows/release-and-update-docker.yml b/.github/workflows/release-and-update-docker.yml deleted file mode 100644 index b1bc86de..00000000 --- a/.github/workflows/release-and-update-docker.yml +++ /dev/null @@ -1,143 +0,0 @@ -name: Auto Release on Main - -on: - push: - branches: - - main - -jobs: - release: - runs-on: ubuntu-latest - permissions: - contents: write - packages: write - steps: - - name: Checkout repository with full history - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Required for go-semantic-release - - - name: Setup Go environment - uses: actions/setup-go@v4 - with: - go-version: '1.22' - - - name: Run Go linter - uses: golangci/golangci-lint-action@v3 - with: - version: latest - - - name: Run Go tests - run: go test -v ./... - - - name: Generate commit summary - id: git-summary - run: | - echo "## Summary" >> commit-summary.md - echo "" >> commit-summary.md - # Count different types of changes - FEATURES=$(git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"%s" --no-merges | grep -i "^feat" | wc -l) - FIXES=$(git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"%s" --no-merges | grep -i "^fix" | wc -l) - DOCS=$(git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"%s" --no-merges | grep -i "^docs" | wc -l) - echo "* $FEATURES new features" >> commit-summary.md - echo "* $FIXES bug fixes" >> commit-summary.md - echo "* $DOCS documentation updates" >> commit-summary.md - echo "" >> commit-summary.md - echo "## Changes since last release" >> commit-summary.md - echo "" >> commit-summary.md - git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"* %s (%h)" --no-merges >> commit-summary.md - echo "COMMIT_SUMMARY<> $GITHUB_ENV - cat commit-summary.md >> $GITHUB_ENV - echo "EOF" >> $GITHUB_ENV - - - name: Run semantic versioning and release - id: semantic-release - uses: go-semantic-release/action@v1 - with: - hooks: goreleaser - changelog: ${{ env.COMMIT_SUMMARY }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} - DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: | - avaprotocol/ap-avs - tags: | - type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }} - type=raw,value={{sha}},enable=${{ github.ref == format('refs/heads/{0}', 'main') }} - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - - - name: Build and push Docker image - if: steps.semantic-release.outputs.new_release_published == 'true' - uses: docker/build-push-action@v6 - with: - build-args: | - RELEASE_TAG=${{ steps.semantic-release.outputs.new_version }} - platforms: linux/amd64,linux/arm64 - context: . - file: dockerfiles/operator.Dockerfile - push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - - deploy: - needs: release - if: needs.release.outputs.new_release_published == 'true' - runs-on: ubuntu-latest - permissions: - actions: write - strategy: - matrix: - workflow: - - id: 'deploy-sepolia.yml' - name: 'Sepolia' - environment: 'Sepolia' - directory: 'sepolia' - - id: 'deploy-base-sepolia.yml' - name: 'Base Sepolia' - environment: 'Base Sepolia' - directory: 'base-sepolia' - - id: 'deploy-base.yml' - name: 'Base' - environment: 'Base' - directory: 'base' - - id: 'deploy-ethereum.yml' - name: 'Ethereum' - environment: 'Ethereum' - directory: 'ethereum' - steps: - - name: Trigger ${{ matrix.workflow.name }} deployment - uses: actions/github-script@v7 - with: - script: | - github.rest.actions.createWorkflowDispatch({ - owner: context.repo.owner, - repo: context.repo.repo, - workflow_id: '${{ matrix.workflow.id }}', - ref: 'main', - inputs: { - tag: '${{ needs.release.outputs.new_version }}', - environment: '${{ matrix.workflow.environment }}', - directory: '${{ matrix.workflow.directory }}' - } - }) \ No newline at end of file From 72234c62898a9093479000de2b3062ec354a5a1b Mon Sep 17 00:00:00 2001 From: chrisli30 Date: Fri, 9 May 2025 17:01:29 -0700 Subject: [PATCH 6/9] =?UTF-8?q?Update=20.github/workflows/deploy-avs.yml?= =?UTF-8?q?=20so=20we=20don=E2=80=99t=20need=20individual=20file=20such=20?= =?UTF-8?q?as=20deploy-base.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy-avs.yml | 24 +++++++++++------------ .github/workflows/deploy-base-sepolia.yml | 21 -------------------- .github/workflows/deploy-base.yml | 17 ---------------- 3 files changed, 11 insertions(+), 51 deletions(-) delete mode 100644 .github/workflows/deploy-base-sepolia.yml delete mode 100644 .github/workflows/deploy-base.yml diff --git a/.github/workflows/deploy-avs.yml b/.github/workflows/deploy-avs.yml index a54fa7fd..c904d919 100644 --- a/.github/workflows/deploy-avs.yml +++ b/.github/workflows/deploy-avs.yml @@ -1,19 +1,17 @@ -name: Reusable Aggregator Deploy +name: Manual AVS Deploy on: - workflow_call: + workflow_dispatch: inputs: environment: + description: 'Target environment for deployment' required: true - type: string - directory: - required: true - type: string - secrets: - AVS_SSH_KEY: - required: true - AVS_SERVER_HOST: - required: true + type: choice + options: + - ethereum + - sepolia + - base + - base-sepolia jobs: aggregator: @@ -33,7 +31,7 @@ jobs: key: ${{ secrets.AVS_SSH_KEY }} script: | echo "Deploying to environment: ${{ inputs.environment }}" - cd $HOME/ap-aggregator-setup/${{ inputs.directory }} + cd $HOME/ap-aggregator-setup/${{ inputs.environment }} docker compose pull docker compose up -d --force-recreate @@ -54,6 +52,6 @@ jobs: key: ${{ secrets.AVS_SSH_KEY }} script: | echo "Deploying to environment: ${{ inputs.environment }}" - cd $HOME/ap-operator-setup/${{ inputs.directory == 'sepolia' && 'holesky' || inputs.directory }} + cd $HOME/ap-operator-setup/${{ inputs.environment == 'sepolia' && 'holesky' || inputs.environment }} docker compose pull docker compose up -d --force-recreate diff --git a/.github/workflows/deploy-base-sepolia.yml b/.github/workflows/deploy-base-sepolia.yml deleted file mode 100644 index 1e2d5dfb..00000000 --- a/.github/workflows/deploy-base-sepolia.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy to Base Sepolia - -on: - workflow_run: - workflows: ["Publish dev build docker image to dockerhub"] - types: - - completed - branches: - - main - workflow_dispatch: - -jobs: - deploy-avs: - #if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.name == 'Push' }} - uses: ./.github/workflows/deploy-avs.yml - with: - environment: "Base Sepolia" - directory: "base-sepolia" - secrets: - AVS_SSH_KEY: ${{ secrets.AVS_SSH_KEY }} - AVS_SERVER_HOST: ${{ secrets.AVS_SERVER_HOST }} \ No newline at end of file diff --git a/.github/workflows/deploy-base.yml b/.github/workflows/deploy-base.yml deleted file mode 100644 index 02c66d2d..00000000 --- a/.github/workflows/deploy-base.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Deploy to Base - -on: - push: - tags: - - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 - workflow_dispatch: - -jobs: - deploy-avs: - uses: ./.github/workflows/deploy-avs.yml - with: - environment: Base - directory: base - secrets: - AVS_SSH_KEY: ${{ secrets.AVS_SSH_KEY }} - AVS_SERVER_HOST: ${{ secrets.AVS_SERVER_HOST }} \ No newline at end of file From ab005121f90f29894943d9b5dd9534907a473aee Mon Sep 17 00:00:00 2001 From: chrisli30 Date: Fri, 9 May 2025 17:08:21 -0700 Subject: [PATCH 7/9] Added release-on-pr-close.yml --- ... prerelease-and-update-docker-on-main.yml} | 0 .github/workflows/release-on-pr-close.yml | 118 ++++++++++++++++++ 2 files changed, 118 insertions(+) rename .github/workflows/{release-and-update-docker-on-main.yml => prerelease-and-update-docker-on-main.yml} (100%) create mode 100644 .github/workflows/release-on-pr-close.yml diff --git a/.github/workflows/release-and-update-docker-on-main.yml b/.github/workflows/prerelease-and-update-docker-on-main.yml similarity index 100% rename from .github/workflows/release-and-update-docker-on-main.yml rename to .github/workflows/prerelease-and-update-docker-on-main.yml diff --git a/.github/workflows/release-on-pr-close.yml b/.github/workflows/release-on-pr-close.yml new file mode 100644 index 00000000..80aa6007 --- /dev/null +++ b/.github/workflows/release-on-pr-close.yml @@ -0,0 +1,118 @@ +name: Create Release and Publish Docker on Main Merge + +on: + pull_request: + types: [closed] + branches: + - main + +jobs: + release-and-publish: + # Only run this job if the PR was merged + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + permissions: + contents: write # Needed for go-semantic-release to create tags and releases + packages: write # If you use GitHub Packages for Docker images (good to have) + steps: + - name: Checkout repository with full history + uses: actions/checkout@v4 + with: + # Fetch all history so go-semantic-release can determine the version based on all commits + fetch-depth: 0 + # We need to check out the main branch itself after the merge, not the PR ref + ref: main + + - name: Setup Go environment + uses: actions/setup-go@v4 + with: + go-version: '1.22' # Or your project's Go version + + # Optional: Add linting and testing steps here if you want to be absolutely sure + # before a release, though these should ideally be covered by PR checks. + # - name: Run Go linter + # uses: golangci/golangci-lint-action@v3 + # with: + # version: latest + # - name: Run Go tests + # run: go test -v ./... + + - name: Generate commit summary for changelog + id: git-summary + run: | + echo "## Summary" >> commit-summary.md + echo "" >> commit-summary.md + # Correctly get commits since the last full tag on the main branch + LAST_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || git rev-list --max-parents=0 HEAD) + echo "Last tag for changelog: $LAST_TAG" + FEATURES=$(git log $LAST_TAG..HEAD --pretty=format:"%s" --no-merges | grep -i "^feat" | wc -l) + FIXES=$(git log $LAST_TAG..HEAD --pretty=format:"%s" --no-merges | grep -i "^fix" | wc -l) + DOCS=$(git log $LAST_TAG..HEAD --pretty=format:"%s" --no-merges | grep -i "^docs" | wc -l) + echo "* $FEATURES new features" >> commit-summary.md + echo "* $FIXES bug fixes" >> commit-summary.md + echo "* $DOCS documentation updates" >> commit-summary.md + echo "" >> commit-summary.md + echo "## Changes since last release ($LAST_TAG)" >> commit-summary.md + echo "" >> commit-summary.md + git log $LAST_TAG..HEAD --pretty=format:"* %s (%h)" --no-merges >> commit-summary.md + echo "COMMIT_SUMMARY<> $GITHUB_ENV + cat commit-summary.md >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + shell: bash + + - name: Run semantic versioning and create full release + id: semantic-release + uses: go-semantic-release/action@v1 + with: + # No pre-release flag needed; it should detect it's on main and do a full release + hooks: goreleaser # Or other hooks you use for release asset generation + changelog: ${{ env.COMMIT_SUMMARY }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Ensure these secrets are set in your repository for DockerHub push + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + + # Docker build and push steps, only if a new release was published + - name: Login to Docker Hub + if: steps.semantic-release.outputs.new_release_published == 'true' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up QEMU + if: steps.semantic-release.outputs.new_release_published == 'true' + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + if: steps.semantic-release.outputs.new_release_published == 'true' + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + if: steps.semantic-release.outputs.new_release_published == 'true' + uses: docker/metadata-action@v5 + with: + images: | + avaprotocol/ap-avs + tags: | + type=raw,value=latest # Push 'latest' tag + type=raw,value=${{ steps.semantic-release.outputs.new_version }} # Push the full version tag (e.g., v1.2.3) + type=semver,pattern={{version}} # Full semver (e.g., v1.2.3) + type=semver,pattern={{major}}.{{minor}} # Major.minor (e.g., v1.2) + type=semver,pattern={{major}} # Major only (e.g., v1) + type=raw,value={{sha}} # Commit SHA + + - name: Build and push Docker image + if: steps.semantic-release.outputs.new_release_published == 'true' + uses: docker/build-push-action@v6 + with: + build-args: | + RELEASE_TAG=${{ steps.semantic-release.outputs.new_version }} + platforms: linux/amd64,linux/arm64 + context: . + file: dockerfiles/operator.Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} From 2884b0f24ce0251c07696037757a3546f9f9ce0a Mon Sep 17 00:00:00 2001 From: chrisli30 Date: Fri, 9 May 2025 17:11:00 -0700 Subject: [PATCH 8/9] Renamed yaml files --- config/aggregator.yaml_sepolia | 35 ----------------------- config/operator.yaml_sepolia | 51 ---------------------------------- 2 files changed, 86 deletions(-) delete mode 100644 config/aggregator.yaml_sepolia delete mode 100644 config/operator.yaml_sepolia diff --git a/config/aggregator.yaml_sepolia b/config/aggregator.yaml_sepolia deleted file mode 100644 index 1fb37574..00000000 --- a/config/aggregator.yaml_sepolia +++ /dev/null @@ -1,35 +0,0 @@ -ecdsa_private_key: f6dc500a34373d7e8af2a4b0b2635253ce1bd92077ed86c24393fb01298abc1d - -eth_rpc_url: https://holesky.gateway.tenderly.co/6PJfDJkrMGBl3f4MuyU5M -eth_ws_url: wss://holesky.gateway.tenderly.co/6PJfDJkrMGBl3f4MuyU5M - -rpc_bind_address: "0.0.0.0:2206" -http_bind_address: "0.0.0.0:8080" - -avs_registry_coordinator_address: 0x90c6d6f2A78d5Ce22AB8631Ddb142C03AC87De7a -operator_state_retriever_address: 0xb7bb920538e038DFFEfcB55caBf713652ED2031F - -etherscan_url: https://etherscan.io -eigenlayer_url: https://app.eigenlayer.xyz - -environment: development -db_path: /tmp/ap-avs/db - -jwt_secret: 1b7db1c64236d92de3b3ed32e5d6bf56 - -# account abstraction config -# Sepolia -smart_wallet: - eth_rpc_url: https://ethereum-sepolia.core.chainstack.com/2504cb0765f0edf6c33d99095148006f - eth_ws_url: wss://ethereum-sepolia.core.chainstack.com/2504cb0765f0edf6c33d99095148006f - bundler_url: https://bundler-sepolia.avaprotocol.org/?apikey=kt8qTj8MtmAQGsj17Urz1aMATV1ySn4R - factory_address: 0x29adA1b5217242DEaBB142BC3b1bCfFdd56008e7 - entrypoint_address: 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 - - # master key to generate and sign userops for any wallet - # wallet: 0xafDe18682A3ee10E4FA2DDE582CdAd24b939C36F - controller_private_key: fa8f65b36c4b312aa4950e475f314c34d273ec3d841a765843926fd00e314563 - -macros: - secrets: - ap_notify_bot_token: "7771086042:AAG7UvbAyN8_8OrS-MjRfwz8WpWDKf4Yw8U" # Telegram bot token for notifications diff --git a/config/operator.yaml_sepolia b/config/operator.yaml_sepolia deleted file mode 100644 index 64d89f8c..00000000 --- a/config/operator.yaml_sepolia +++ /dev/null @@ -1,51 +0,0 @@ -# this sets the logger level (true = info, false = debug) -production: false - -operator_address: 0x997E5D40a32c44a3D93E59fC55C4Fd20b7d2d49D - -avs_registry_coordinator_address: 0x90c6d6f2A78d5Ce22AB8631Ddb142C03AC87De7a -operator_state_retriever_address: 0xb7bb920538e038DFFEfcB55caBf713652ED2031F - -eth_rpc_url: https://ethereum-holesky-rpc.publicnode.com -eth_ws_url: wss://eth-holesky.g.alchemy.com/v2/A1UDofV6tMUsH4dvA4mmUCtQp_oPX7lL - -# If you running this using eigenlayer CLI and the provided AVS packaging structure, -# this should be /operator_keys/ecdsa_key.json as the host path will be asked while running -# -# If you are running locally using go run main.go, this should be full path to your local ecdsa key file -ecdsa_private_key_store_path: /Users/mikasa/Code/EigenLayer-AVS/keys/vinh.ecdsa.key.json -#ecdsa_private_key_store_path: alias-ecdsa.key.json - -# If you running this using eigenlayer CLI and the provided AVS packaging structure, -# this should be /operator_keys/bls_key.json as the host path will be asked while running -# -# We are using bn254 curve for bls keys -# -# If you are running locally using go run main.go, this should be full path to your local bls key file -bls_private_key_store_path: /Users/mikasa/Code/EigenLayer-AVS/keys/vinh.bls.key.json - -# When setting remote signer, we can skip bls_private_key_store_path -# bls_remote_signer: -# grpc_url: "127.0.0.1:50051" -# public_key: "a2e8430e4c3932f33260b4346ab9845ce6192c5ca6472f3a481eaaa02d066d0a" -# password: "c4a7c49604164fe9cb10e6fc52afdca7f39a" - -# address which the aggregator listens on for operator signed messages -aggregator_server_ip_port_address: - "127.0.0.1:2206" - #aggregator_server_ip_port_address: "aggregator-holesky.avaprotocol.org:2206" - -# avs node spec compliance https://eigen.nethermind.io/docs/spec/intro -eigen_metrics_ip_port_address: localhost:9090 -enable_metrics: true -node_api_ip_port_address: localhost:9010 -enable_node_api: true - -db_path: /tmp/ap-avs-operator - -# Destination chain -target_chain: - eth_rpc_url: https://ethereum-sepolia.core.chainstack.com/2504cb0765f0edf6c33d99095148006f - eth_ws_url: wss://ethereum-sepolia.core.chainstack.com/2504cb0765f0edf6c33d99095148006f - #eth_rpc_url: https://api-soneium-minato.dwellir.com/b656fef0-86c1-4020-adbd-dc01efa33fb0 - #eth_ws_url: wss://api-soneium-minato.dwellir.com/b656fef0-86c1-4020-adbd-dc01efa33fb0 From 68350ed16a2c587ae7b43ddda0219e6eb9559506 Mon Sep 17 00:00:00 2001 From: chrisli30 Date: Fri, 9 May 2025 17:17:18 -0700 Subject: [PATCH 9/9] Updated RELEASE.md --- RELEASE.md | 124 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 72 insertions(+), 52 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index fc630a23..68484764 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -2,83 +2,103 @@ ## Overview -The release process follows a staged approach from development to production, with specific Docker image management for each stage. +The release process follows a staged approach from development to production, with specific Docker image management for each stage, automated via GitHub Actions. ## Branch and Docker Image Alignment -| Environment | Github Branch | Docker Image Repository | Docker Tag Format | Managed By | Trigger Condition | -| ----------- | ------------- | ---------------------------- | -------------------------- | ------------------------------- | ------------------------------------------------- | -| Development | `dev` | `avaprotocol/ap-avs-dev` | `commit-hash` | GA: `update-docker-dev` | Manual trigger against dev branch | -| Staging | `staging` | `avaprotocol/ap-avs-staging` | `commit-hash` | GA: `update-docker-staging` | Automatic on PR merge to staging branch | -| Production | `main` | `avaprotocol/ap-avs` | `x.y.z` (semantic version) | GA: `release-and-update-docker` | Automatic on PR merge from staging to main | -| Mainnet | `mainnet` | `avaprotocol/ap-avs` | `mainnet` | GA: `update-docker-mainnet` | Manual trigger to sync main to mainnet and deploy | +| Environment | Github Branch | Docker Image Repository | Docker Tag Format | Managed By | Trigger Condition | +| ----------------------- | --------------- | ---------------------------- | ------------------------------------- | --------------------------------------------------- | -------------------------------------------------------- | +| Development | `dev` | N/A | N/A | N/A | N/A | +| Staging | `staging` | `avaprotocol/avs-dev` | `pr-XXX` (PR number) | `publish-dev-docker-on-staging.yml` | Automatic on PR merge to `staging` | +| **Production (PR)** | `main` (PR) | `avaprotocol/ap-avs` | `vX.Y.Z-rc.N` (pre-release) | `prerelease-and-update-docker-on-main.yml` | Automatic on PR opened/synchronized to `main` | +| **Production (Release)**| `main` (Merged) | `avaprotocol/ap-avs` | `vX.Y.Z` (stable), `latest`, etc. | `release-on-pr-close.yml` | Automatic on PR merged to `main` | ### Environment Details -- **Staging Branch**: +- **Staging Branch (`staging`)**: + - Serves as a testing and integration pool before changes are promoted. + - The `avaprotocol/avs-dev` Docker image is updated with a `pr-XXX` tag (where XXX is the PR number) after each pull request from a `dev` branch is merged into `staging`. This is handled by the `publish-dev-docker-on-staging.yml` workflow. + - Changes in `staging` are considered pre-production. - - This branch serves as a caching and testing pool before changes are merged into main - - The staging Docker image is updated after each PR merge from dev branches. - - Changes in staging are considered pre-production and not yet live +- **Main Branch (`main`)**: + - This branch reflects production-ready code. The release process for `main` is two-phased: + 1. **Pre-release on Pull Request**: When a Pull Request is opened or updated targeting `main`, the `prerelease-and-update-docker-on-main.yml` workflow automatically builds a pre-release Docker image tagged like `vX.Y.Z-rc.N` (e.g., `v0.5.0-rc.1`) and creates a corresponding GitHub pre-release. This allows for testing the exact build that could become a full release. + 2. **Full Release on Merge**: Upon merging a Pull Request into `main`, the `release-on-pr-close.yml` workflow is triggered. This workflow creates a full GitHub Release with a stable semantic version (e.g., `v0.5.0`), and builds and publishes the `avaprotocol/ap-avs` Docker image tagged with this stable version, `latest`, and other semantic version tags (e.g., `v0.5`). + - Deployments to production environments are typically done manually after a stable version is released. -- **Main Branch**: +- **Mainnet Branch (`mainnet`)**: + - Uses non-fast-forward merge to preserve mainnet-specific changes (e.g., different EigenSDK version). + - After testing the stable Docker image (from `main` branch releases) on test environments, a separate process (potentially a manual trigger of a dedicated workflow like `update-docker-mainnet`, not detailed in the provided workflow files) is used to update the `avaprotocol/ap-avs:mainnet` tag. + - Operators automatically download and upgrade their images when the `mainnet` tag is updated. + - Requires manual intervention for promoting a version to the `mainnet` Docker tag and for deployment. - - Docker images are automatically built and published after merging into main - - Creates a GitHub Release with the semantic versioning (x.y.z) and for image tags - - Deploys to all environments (Ethereum, Base, etc.). Each environment uses the same version but different configurations +### Important Notes (EigenSDK on Mainnet) -- **Mainnet Branch**: - - Uses non-fast-forward merge to preserve mainnet-specific changes (different EigenSDK version) - - After testing the Docker image on test environments, we run `update-docker-mainnet` to officially update the `avaprotocol/ap-avs@mainnet` tag - - Operators automatically download and upgrade their images when the mainnet tag is updated - - Requires manual trigger for deployment - +Due to the EigenSDK package difference on Ethereum mainnet, the implementation of the EigenSDK on the `mainnet` branch has diverged from `main`. For updating the `avaprotocol/ap-avs:mainnet` Docker image, a dedicated process (e.g., the `update-docker-mainnet` workflow) typically performs the following: -### Important Notes - -Due to the EigenSDK package difference on Ethereum mainnet, the implementation of the EigenSDK on `mainnet` branched out from `main`. For updating the `avaprotocol/ap-avs@mainnet` docker, the `update-docker-mainnet` GA perform the below actions. - -1. Merge the working code from `main` to `mainnet` -2. Build Docker image from `mainnet` -3. Publish the docker to the `avaprotocol/ap-avs@mainnet` tag. +1. Merge the working code from `main` (or a specific release tag) to `mainnet`. +2. Build a Docker image from the `mainnet` branch. +3. Publish this Docker image to `avaprotocol/ap-avs:mainnet`. ## Versioning and Releasing -The versioning process is automated and triggered when code is merged from `staging` to `main` through a pull request. The `release-on-pr` GitHub Action handles this process using `go-semantic-release`. +The versioning process is automated using `go-semantic-release` within GitHub Actions. ### Commit Message Format -For versioning to work correctly, commit messages must follow the conventional commit format: +For versioning to work correctly, commit messages **must** follow the Conventional Commits format: + +- `feat:` for new features (results in a minor version bump for stable releases, or contributes to pre-release versioning). +- `fix:` for bug fixes (results in a patch version bump for stable releases, or contributes to pre-release versioning). +- `docs:` for documentation changes (typically no version bump by `go-semantic-release` unless configured otherwise). +- `BREAKING CHANGE:` in the commit body, or `type!:` (e.g., `feat!:`) for breaking changes (results in a major version bump for stable releases). + +### Release Process for `main` Branch + +The release process targeting the `main` branch involves two key automated workflows: + +**A. Pre-release on Pull Request to `main` (via `prerelease-and-update-docker-on-main.yml`)** + +This workflow triggers when a Pull Request is opened or synchronized against the `main` branch: + +1. **Pre-release Version Determination**: + - `go-semantic-release` analyzes commit messages in the PR. + - Determines the next pre-release version number (e.g., `v0.5.0-rc.1`, where `rc.1` might increment on subsequent pushes to the PR). + +2. **Pre-release Creation**: + - Creates a GitHub Pre-Release with the new pre-release version. + - Creates a Git tag for the pre-release version (e.g., `v0.5.0-rc.1`). -- `feat:` for new features (minor version bump) -- `fix:` for bug fixes (patch version bump) -- `docs:` for documentation changes (no version bump) -- `BREAKING CHANGE:` or `feat!:` for breaking changes (major version bump) +3. **Docker Image Build and Push**: + - Builds a Docker image from the PR's code. + - Publishes the image to `avaprotocol/ap-avs` tagged only with the specific pre-release version (e.g., `avaprotocol/ap-avs:v0.5.0-rc.1`). The `latest` tag is **not** updated at this stage. -### Release Process +**B. Full Release on Pull Request Merge to `main` (via `release-on-pr-close.yml`)** -When a PR from `staging` to `main` is merged, the following happens automatically: +This workflow triggers when a Pull Request is closed and merged into the `main` branch: -1. Version Determination: +1. **Stable Version Determination**: + - `go-semantic-release` analyzes commit messages on the `main` branch since the last stable release. + - Determines the next stable semantic version number (e.g., `v0.5.0`). - - Analyzes commit messages since the last release - - Determines the next version number based on commit types - - Major version for breaking changes - - Minor version for new features - - Patch version for bug fixes +2. **Full Release Creation**: + - Creates a GitHub Full Release with the new stable version and a generated changelog. + - Creates a Git tag for the stable version (e.g., `v0.5.0`). -2. Release Creation: +3. **Docker Image Build and Push**: + - Builds a Docker image from the merged code on `main`. + - Publishes the image to `avaprotocol/ap-avs` with multiple tags: + - The stable version (e.g., `avaprotocol/ap-avs:v0.5.0`). + - `latest` (i.e., `avaprotocol/ap-avs:latest`). + - Other semantic tags like major.minor (e.g., `v0.5`) and major (e.g., `v0`). - - Creates a GitHub Release with the new version - - Builds and publishes Docker image to `avaprotocol/ap-avs` with version tag - - Does NOT create Git tags automatically +### Deployment -3. Deployment: - - Triggers deployments to all environments, currently `Sepolia`, `Base Sepolia`, `Ethereum` and `Base`. - - Each environment uses the same version and docker image, but vary on `environment` and `directory`. +- Deployments to various environments (e.g., `Sepolia`, `Base Sepolia`, `Ethereum`, `Base`) are handled by the **manual** GitHub Action workflow: `deploy-avs.yml`. +- To deploy, a user manually triggers this workflow, selecting the target environment and the version (implicitly by deploying the code from a specific branch, usually `main` for production environments after a release, or `staging` for staging environments). +- Each environment uses the same Docker image version (for a given release) but varies in runtime configuration. ### Important Notes -- Docker images are tagged with the version number such as `x.y.z` -- The `latest` tag of Docker image is not automatically updated -- Git tags need to be created manually if needed +- Docker images are tagged as described above: pre-releases for PRs to `main`, and stable versions + `latest` upon merge to `main`. +- Git tags (both for pre-releases and full releases) are created **automatically** by `go-semantic-release` as part of the respective workflows.