From 7dce828abe91efedb689b617e95ef898e761b36c Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Thu, 4 Sep 2025 15:52:59 +0000 Subject: [PATCH 01/27] feature: revamp release workflow with dynamic release notes generation Adds a new setup job for generating release notes using git-cliff, injects test configuration into notes, and creates pre-releases via GitHub API. Refactors workflow for improved clarity and maintainability. --- .github/workflows/release.yml | 449 +++++++++++++++++++++------------- 1 file changed, 283 insertions(+), 166 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7fac1aa0b..94a61e24c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,177 +1,294 @@ name: Release on: - push: - tags: - - "v*.*.*" - - "v*.*.*-*" + push: + branches: + - feat/ci-revamp + tags: + - "v*.*.*" + - "v*.*.*-*" concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true permissions: - contents: write - packages: write + contents: write + packages: write env: - REGISTRY: ghcr.io - REGISTRY_IMAGE: ghcr.io/${{ github.repository }} - REGEX_IMAGE: ${{ github.repository }}:\\d+.\\d+.\\d+ + REGISTRY: ghcr.io + REGISTRY_IMAGE: ghcr.io/${{ github.repository }} + REGEX_IMAGE: ${{ github.repository }}:\\d+.\\d+.\\d+ jobs: - build: - runs-on: amd-runner-2204 - strategy: - fail-fast: false - matrix: - platform: - - linux/amd64 - - linux/arm64 - variant: - - { suffix: "", include_shell: "false", description: "production" } - - { - suffix: "-dev", - include_shell: "true", - description: "development", - } - outputs: - IMAGE_NAME_PROD: ${{ steps.image_builder_prod.outputs.IMAGE }} - IMAGE_NAME_DEV: ${{ steps.image_builder_dev.outputs.IMAGE }} - TAGS_PROD: ${{ steps.meta_prod.outputs.tags }} - TAGS_DEV: ${{ steps.meta_dev.outputs.tags }} - VERSION: ${{ steps.meta_prod.outputs.version }} - steps: - - name: Prepare - run: | - platform=${{ matrix.platform }} - echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - VARIANT_SUFFIX="${{ matrix.variant.suffix }}" - echo "VARIANT_SUFFIX=$VARIANT_SUFFIX" >> $GITHUB_ENV - PLATFORM_VARIANT="${platform//\//-}${VARIANT_SUFFIX}" - echo "PLATFORM_VARIANT=$PLATFORM_VARIANT" >> $GITHUB_ENV - - - name: Checkout - uses: actions/checkout@v5 - - - name: Docker meta (prod) - id: meta_prod - if: matrix.variant.suffix == '' - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY_IMAGE }} - tags: | - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - - - name: Docker meta (dev) - id: meta_dev - if: matrix.variant.suffix != '' - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY_IMAGE }} - tags: | - type=ref,event=branch,suffix=-dev - type=ref,event=pr,suffix=-dev - type=semver,pattern={{version}}-dev - type=semver,pattern={{major}}.{{minor}}-dev - - - name: Image name builder (prod) - id: image_builder_prod - if: matrix.variant.suffix == '' - run: | - IMAGE=$(jq -ecr '.tags | map(select(match("${{ env.REGEX_IMAGE }}", "i"))) | first| sub(":.*$";"")' <<< "$DOCKER_METADATA_OUTPUT_JSON") - echo "IMAGE=$IMAGE" >> $GITHUB_OUTPUT - - - name: Image name builder (dev) - id: image_builder_dev - if: matrix.variant.suffix != '' - run: | - IMAGE=$(jq -ecr '.tags | map(select(match("${{ env.REGEX_IMAGE }}-dev", "i"))) | first| sub(":.*$";"")' <<< "$DOCKER_METADATA_OUTPUT_JSON") - echo "IMAGE=$IMAGE" >> $GITHUB_OUTPUT - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Build and push by digest - id: build - uses: docker/build-push-action@v6 - with: - context: . - push: false - platforms: ${{ matrix.platform }} - labels: ${{ (matrix.variant.suffix == '') && steps.meta_prod.outputs.labels || steps.meta_dev.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max - build-args: | - INCLUDE_SHELL=${{ matrix.variant.include_shell }} - outputs: type=image,name=${{ (matrix.variant.suffix == '') && steps.image_builder_prod.outputs.IMAGE || steps.image_builder_dev.outputs.IMAGE }},push-by-digest=true,push=true - - - name: Export digest - run: | - mkdir -p /tmp/digests - digest="${{ steps.build.outputs.digest }}" - touch "/tmp/digests/${digest#sha256:}.${{ env.PLATFORM_VARIANT }}" - - - name: Upload digest - uses: actions/upload-artifact@v4 - with: - name: digests-${{ env.PLATFORM_VARIANT }} - path: /tmp/digests/* - if-no-files-found: error - retention-days: 1 - - merge: - runs-on: arm-runner-2204 - needs: - - build - strategy: - matrix: - variant: - - { suffix: "", description: "production" } - - { suffix: "-dev", description: "development" } - steps: - - name: Download digests - uses: actions/download-artifact@v4 - with: - path: /tmp/digests - pattern: digests-*${{ matrix.variant.suffix }} - merge-multiple: true - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Create manifest list and push - working-directory: /tmp/digests - run: | - IMAGE_NAME="${{ (matrix.variant.suffix == '') && needs.build.outputs.IMAGE_NAME_PROD || needs.build.outputs.IMAGE_NAME_DEV }}" - TAGS="${{ (matrix.variant.suffix == '') && needs.build.outputs.TAGS_PROD || needs.build.outputs.TAGS_DEV }}" - docker buildx imagetools create $(jq -cRr 'split("\n") | map(gsub("\\s+";"")) | map("-t "+ .) | join(" ")' <<< "$TAGS") \ - $(for f in *${{ matrix.variant.suffix }}; do echo "${IMAGE_NAME}@sha256:${f%%.*}"; done) - - - name: Inspect image - run: | - IMAGE_NAME="${{ (matrix.variant.suffix == '') && needs.build.outputs.IMAGE_NAME_PROD || needs.build.outputs.IMAGE_NAME_DEV }}" - TAGS="${{ (matrix.variant.suffix == '') && needs.build.outputs.TAGS_PROD || needs.build.outputs.TAGS_DEV }}" - # Use the first tag for inspection - FIRST_TAG=$(echo "$TAGS" | head -n1) - docker buildx imagetools inspect "$FIRST_TAG" + setup: + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ github.token }} + outputs: + release-id: ${{ steps.create-release.outputs.release-id }} + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 0 # Needed for git-cliff to access commit history + + # Step 1: Set up git-cliff + - name: Setup git-cliff + uses: kenji-miyake/setup-git-cliff@v1 + + # Step 2: Generate dynamic release notes template + - name: Generate release notes + id: generate-notes + run: | + TAG_VERSION="${{ github.ref_name }}" + + echo "๐Ÿ“ Generating release notes for $TAG_VERSION..." + + # Generate release notes with git-cliff + git-cliff --latest --output release_notes.md || { + echo "โš ๏ธ git-cliff failed, creating fallback release notes" + + # Get previous tag for fallback + PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") + + # Create fallback content with proper tag handling + if [ -n "$PREVIOUS_TAG" ] && [ "$PREVIOUS_TAG" != "$TAG_VERSION" ]; then + CHANGELOG_LINK="https://github.com/${{ github.repository }}/compare/$PREVIOUS_TAG...$TAG_VERSION" + else + CHANGELOG_LINK="https://github.com/${{ github.repository }}/commits/$TAG_VERSION" + fi + + cat > release_notes.md << EOF + ## ๐Ÿš€ What's New + - [Brief description of new features] + + ## โœ… Testing & Validation + + + + ## ๐Ÿ“ฆ Full Changelog + See the [full changelog]($CHANGELOG_LINK) for detailed changes. + EOF + } + + # Always replace the test placeholder with dynamic test list (whether git-cliff succeeds or fails) + TEST_LINES=$(echo '${{ env.TEST_CONFIG }}' | jq -r '.[] | "- **" + .name + "**: [Running...](#)"') + + # Replace placeholder in release notes + if [ -n "$TEST_LINES" ]; then + # Create replacement content + cat > replacement_content.tmp << EOF + + $TEST_LINES + + EOF + + # Replace placeholder section + sed -i '//,//d' release_notes.md + sed -i '/## โœ… Testing & Validation/r replacement_content.tmp' release_notes.md + + # Clean up + rm -f replacement_content.tmp + else + echo "โš ๏ธ No test configuration found, using default placeholder" + fi + + echo "โœ… Release notes generated" + + # Step 3: Create pre-release + - name: Create pre-release + id: create-release + run: | + TAG_VERSION="${{ github.ref_name }}" + + echo "๐Ÿ“ฆ Creating pre-release: $TAG_VERSION" + + # Get previous tag for comparison link + PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") + + # Read the generated release notes + RELEASE_NOTES=$(cat release_notes.md) + + # Add header with tag comparison link if we have a previous tag + if [ -n "$PREVIOUS_TAG" ] && [ "$PREVIOUS_TAG" != "$TAG_VERSION" ]; then + HEADER="**Full Changelog**: [\`$PREVIOUS_TAG...$TAG_VERSION\`](https://github.com/${{ github.repository }}/compare/$PREVIOUS_TAG...$TAG_VERSION)"$'\n\n' + else + HEADER="**Full Changelog**: [View all commits](https://github.com/${{ github.repository }}/commits/$TAG_VERSION)"$'\n\n' + fi + + FULL_NOTES="$HEADER$RELEASE_NOTES" + + # Create pre-release using git-cliff generated notes + RELEASE_DATA=$(gh api repos/${{ github.repository }}/releases \ + --method POST \ + --field tag_name="$TAG_VERSION" \ + --field name="$TAG_VERSION" \ + --field body="$FULL_NOTES" \ + --field draft=false \ + --field prerelease=true) + + RELEASE_ID=$(echo "$RELEASE_DATA" | jq -r '.id') + echo "release-id=$RELEASE_ID" >> $GITHUB_OUTPUT + echo "โœ… Created pre-release: $TAG_VERSION (ID: $RELEASE_ID)" + + build: + runs-on: amd-runner-2204 + strategy: + fail-fast: false + matrix: + platform: + - linux/amd64 + - linux/arm64 + variant: + - { + suffix: "", + include_shell: "false", + description: "production", + } + - { + suffix: "-dev", + include_shell: "true", + description: "development", + } + outputs: + IMAGE_NAME_PROD: ${{ steps.image_builder_prod.outputs.IMAGE }} + IMAGE_NAME_DEV: ${{ steps.image_builder_dev.outputs.IMAGE }} + TAGS_PROD: ${{ steps.meta_prod.outputs.tags }} + TAGS_DEV: ${{ steps.meta_dev.outputs.tags }} + VERSION: ${{ steps.meta_prod.outputs.version }} + steps: + - name: Prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + VARIANT_SUFFIX="${{ matrix.variant.suffix }}" + echo "VARIANT_SUFFIX=$VARIANT_SUFFIX" >> $GITHUB_ENV + PLATFORM_VARIANT="${platform//\//-}${VARIANT_SUFFIX}" + echo "PLATFORM_VARIANT=$PLATFORM_VARIANT" >> $GITHUB_ENV + + - name: Checkout + uses: actions/checkout@v5 + + - name: Docker meta (prod) + id: meta_prod + if: matrix.variant.suffix == '' + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY_IMAGE }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + + - name: Docker meta (dev) + id: meta_dev + if: matrix.variant.suffix != '' + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY_IMAGE }} + tags: | + type=ref,event=branch,suffix=-dev + type=ref,event=pr,suffix=-dev + type=semver,pattern={{version}}-dev + type=semver,pattern={{major}}.{{minor}}-dev + + - name: Image name builder (prod) + id: image_builder_prod + if: matrix.variant.suffix == '' + run: | + IMAGE=$(jq -ecr '.tags | map(select(match("${{ env.REGEX_IMAGE }}", "i"))) | first| sub(":.*$";"")' <<< "$DOCKER_METADATA_OUTPUT_JSON") + echo "IMAGE=$IMAGE" >> $GITHUB_OUTPUT + + - name: Image name builder (dev) + id: image_builder_dev + if: matrix.variant.suffix != '' + run: | + IMAGE=$(jq -ecr '.tags | map(select(match("${{ env.REGEX_IMAGE }}-dev", "i"))) | first| sub(":.*$";"")' <<< "$DOCKER_METADATA_OUTPUT_JSON") + echo "IMAGE=$IMAGE" >> $GITHUB_OUTPUT + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push by digest + id: build + uses: docker/build-push-action@v6 + with: + context: . + push: false + platforms: ${{ matrix.platform }} + labels: ${{ (matrix.variant.suffix == '') && steps.meta_prod.outputs.labels || steps.meta_dev.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + build-args: | + INCLUDE_SHELL=${{ matrix.variant.include_shell }} + outputs: type=image,name=${{ (matrix.variant.suffix == '') && steps.image_builder_prod.outputs.IMAGE || steps.image_builder_dev.outputs.IMAGE }},push-by-digest=true,push=true + + - name: Export digest + run: | + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}.${{ env.PLATFORM_VARIANT }}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-${{ env.PLATFORM_VARIANT }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: arm-runner-2204 + needs: + - build + strategy: + matrix: + variant: + - { suffix: "", description: "production" } + - { suffix: "-dev", description: "development" } + steps: + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: /tmp/digests + pattern: digests-*${{ matrix.variant.suffix }} + merge-multiple: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + IMAGE_NAME="${{ (matrix.variant.suffix == '') && needs.build.outputs.IMAGE_NAME_PROD || needs.build.outputs.IMAGE_NAME_DEV }}" + TAGS="${{ (matrix.variant.suffix == '') && needs.build.outputs.TAGS_PROD || needs.build.outputs.TAGS_DEV }}" + docker buildx imagetools create $(jq -cRr 'split("\n") | map(gsub("\\s+";"")) | map("-t "+ .) | join(" ")' <<< "$TAGS") \ + $(for f in *${{ matrix.variant.suffix }}; do echo "${IMAGE_NAME}@sha256:${f%%.*}"; done) + + - name: Inspect image + run: | + IMAGE_NAME="${{ (matrix.variant.suffix == '') && needs.build.outputs.IMAGE_NAME_PROD || needs.build.outputs.IMAGE_NAME_DEV }}" + TAGS="${{ (matrix.variant.suffix == '') && needs.build.outputs.TAGS_PROD || needs.build.outputs.TAGS_DEV }}" + # Use the first tag for inspection + FIRST_TAG=$(echo "$TAGS" | head -n1) + docker buildx imagetools inspect "$FIRST_TAG" From c7f14bc45a679dd786350f02157380d641c60e32 Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Thu, 4 Sep 2025 15:59:22 +0000 Subject: [PATCH 02/27] Set release draft to true and add git-cliff config --- .github/workflows/release.yml | 2 +- cliff.toml | 125 ++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 cliff.toml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 94a61e24c..8b0d9aacd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -126,7 +126,7 @@ jobs: --field tag_name="$TAG_VERSION" \ --field name="$TAG_VERSION" \ --field body="$FULL_NOTES" \ - --field draft=false \ + --field draft=true \ --field prerelease=true) RELEASE_ID=$(echo "$RELEASE_DATA" | jq -r '.id') diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 000000000..d2f66a74b --- /dev/null +++ b/cliff.toml @@ -0,0 +1,125 @@ +# git-cliff configuration file +# https://git-cliff.org/docs/configuration + +[changelog] +# changelog header +header = """ +# Changelog + +All notable changes to this project will be documented in this file. + +""" +# template for the changelog body +# config_change_commits is a list of commits that have a CONFIG-CHANGE footer +# and is built here instead of using a group so that the commits are still grouped +# in their original groups (a commit cannot be in multiple groups). +# https://keats.github.io/tera/docs/#introduction +body = """ + +{%- set breaking_commits = commits | filter(attribute="breaking", value=true) -%} +{%- set config_change_commits = [] -%} +{%- for commit in commits -%} + {%- for footer in commit.footers -%} + {%- if footer.token == 'CONFIG-CHANGE' -%} + {%- set_global config_change_commits = config_change_commits | concat(with=commit) -%} + {%- endif -%} + {%- endfor -%} +{%- endfor -%} + +## ๐Ÿš€ What's New +- [Brief description of new features] + +## โœ… Testing & Validation + + + +{% if breaking_commits %} + ## โš ๏ธ Breaking Changes + {%- for commit in breaking_commits %} + {%- for line in commit.footers %} + {%- if line.breaking %} + - {{ line.value | trim }} + ***Original commit:*** {% if commit.type %}{{ commit.type }}{% endif -%}{% if commit.scope %}(_{{commit.scope}}_){% endif -%} {{ commit.message | trim }} + {%- endif %} + {%- endfor %} + {%- endfor %} +{%- endif %} + +{% if config_change_commits %} + ## ๐Ÿ“‹ Configuration Changes + {%- for commit in config_change_commits %} + {%- for line in commit.footers %} + {%- if line.token == 'CONFIG-CHANGE' %} + - {{ line.value | trim }} + ***Original commit:*** {% if commit.type %}{{ commit.type }}{% endif -%}{% if commit.scope %}(_{{commit.scope}}_){% endif -%} {{ commit.message | trim }} + {%- endif %} + {%- endfor %} + {%- endfor %} +{%- endif %} + +## ๐Ÿ“ฆ Full Changelog +{% for group, group_commits in commits | group_by(attribute="group") %} + ### {{ group | striptags | trim | upper_first }} + {% for commit in group_commits %} + - {% if commit.scope %}(_{{commit.scope}}_) {% endif -%} {{ commit.message | upper_first | trim }} + {%- endfor -%} +{% endfor %} +""" +# remove the leading and trailing whitespace from the templates +trim = true +# changelog footer +footer = """ + +""" +# postprocessors +postprocessors = [ + # { pattern = '', replace = "https://github.com/orhun/git-cliff" }, # replace repository URL +] + +[git] +# parse the commits based on https://www.conventionalcommits.org +conventional_commits = true +# filter out the commits that are not conventional +filter_unconventional = true +# process each line of a commit as an individual commit +split_commits = false +# regex for preprocessing the commit messages +commit_preprocessors = [ + # Replace issue numbers + #{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](/issues/${2}))"}, + # Check spelling of the commit with https://github.com/crate-ci/typos + # If the spelling is incorrect, it will be automatically fixed. + # { pattern = '.*', replace_command = 'typos --write-changes -' }, + # { pattern = '\-\s\[\s] I have .*', replace = "" }, +] +# regex for parsing and grouping commits +commit_parsers = [ + # Regular commit types - message-based grouping only + { message = "^feat", group = "๐Ÿš€ Features" }, + { message = "^fix", group = "๐Ÿ› Bug Fixes" }, + { message = "^doc", group = "๐Ÿ“š Documentation" }, + { message = "^perf", group = "โšก Performance" }, + { message = "^refactor", group = "๐Ÿšœ Refactor" }, + { message = "^style", group = "๐ŸŽจ Styling" }, + { message = "^test", group = "๐Ÿงช Testing" }, + { message = "^ci", group = "๐Ÿค– CI" }, + { message = "^chore", group = "โš™๏ธ Miscellaneous Tasks" }, + { message = "^\\[(.*)\\]", group = "๐Ÿ“ฆ Uncategorized" }, +] +# protect breaking changes from being skipped due to matching a skipping pattern +protect_breaking_commits = false +# filter out the commits that are not matched by commit parsers +filter_commits = true +# regex for matching git tags +# tag_pattern = "v[0-9].*" + +# regex for skipping tags +# skip_tags = "" +# regex for ignoring tags +# ignore_tags = "" +# sort the tags topologically +topo_order = false +# sort the commits inside sections by oldest/newest order +sort_commits = "oldest" +# limit the number of commits included in the changelog. +# limit_commits = 42 From bddc596bb1bfa4d3f0c99c9cc510c596f7a27633 Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Fri, 5 Sep 2025 09:57:01 +0000 Subject: [PATCH 03/27] Add test configuration parsing to release workflow --- .github/workflows/release.yml | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8b0d9aacd..06967f9cf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,6 +20,26 @@ env: REGISTRY: ghcr.io REGISTRY_IMAGE: ghcr.io/${{ github.repository }} REGEX_IMAGE: ${{ github.repository }}:\\d+.\\d+.\\d+ + # Configuration: Customize your test suite here + # Each test configuration includes: name, workflow, allow-failure + TEST_CONFIG: | + [ + { + "name": "Unit Tests", + "workflow": "./.github/workflows/test-unit.yml", + "allow_failure": false + }, + { + "name": "Integration Tests", + "workflow": "./.github/workflows/test-e2e.yml", + "allow_failure": true + }, + { + "name": "Security Scan", + "workflow": "./.github/workflows/govulncheck.yml", + "allow_failure": true + } + ] jobs: setup: @@ -34,6 +54,24 @@ jobs: with: fetch-depth: 0 # Needed for git-cliff to access commit history + # Step 2: Parse test configuration + - name: Parse test configuration + id: parse-config + run: | + echo "๐Ÿ“‹ Parsing test configuration..." + + # Parse the test configuration and extract test names + TEST_NAMES=$(echo '${{ env.TEST_CONFIG }}' | jq -r '.[].name') + + # Create the test configuration output + echo "test-config<> $GITHUB_OUTPUT + echo '${{ env.TEST_CONFIG }}' >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + echo "โœ… Test configuration parsed" + echo "Test names:" + echo "$TEST_NAMES" + # Step 1: Set up git-cliff - name: Setup git-cliff uses: kenji-miyake/setup-git-cliff@v1 @@ -81,6 +119,7 @@ jobs: # Create replacement content cat > replacement_content.tmp << EOF + [![Release](https://github.com/agglayer/aggkit/actions/workflows/release.yml/badge.svg?branch=$TAG_VERSION)](https://github.com/agglayer/aggkit/actions/workflows/release.yml) $TEST_LINES EOF From efb9eeff66f54c30a70bef53c9341d40b672eea2 Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Fri, 5 Sep 2025 10:04:19 +0000 Subject: [PATCH 04/27] Refactor release workflow to use explicit test jobs --- .github/workflows/release.yml | 37 +++++++++++++++-------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 06967f9cf..89e0b7e15 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,26 +20,6 @@ env: REGISTRY: ghcr.io REGISTRY_IMAGE: ghcr.io/${{ github.repository }} REGEX_IMAGE: ${{ github.repository }}:\\d+.\\d+.\\d+ - # Configuration: Customize your test suite here - # Each test configuration includes: name, workflow, allow-failure - TEST_CONFIG: | - [ - { - "name": "Unit Tests", - "workflow": "./.github/workflows/test-unit.yml", - "allow_failure": false - }, - { - "name": "Integration Tests", - "workflow": "./.github/workflows/test-e2e.yml", - "allow_failure": true - }, - { - "name": "Security Scan", - "workflow": "./.github/workflows/govulncheck.yml", - "allow_failure": true - } - ] jobs: setup: @@ -172,8 +152,23 @@ jobs: echo "release-id=$RELEASE_ID" >> $GITHUB_OUTPUT echo "โœ… Created pre-release: $TAG_VERSION (ID: $RELEASE_ID)" - build: + # Dynamic test jobs - calling reusable workflows as black boxes + unit-tests: + needs: setup + uses: ./.github/workflows/test-unit.yml + + integration-tests: + needs: setup + uses: ./.github/workflows/test-e2e.yml + + security-scan: + needs: setup + uses: ./.github/workflows/govulncheck.yml + + promote: runs-on: amd-runner-2204 + needs: [setup, unit-tests, integration-tests, security-scan] + if: needs.setup.outputs.version-changed == 'true' && needs.unit-tests.result == 'success' && needs.integration-tests.result == 'success' && needs.security-scan.result == 'success' strategy: fail-fast: false matrix: From f97fa8db6aa9fe746a83ab0c8c8d35f16b06abf9 Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Fri, 5 Sep 2025 10:06:03 +0000 Subject: [PATCH 05/27] Rename promote job to build in release workflow --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 89e0b7e15..e5e4d76d8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -165,7 +165,7 @@ jobs: needs: setup uses: ./.github/workflows/govulncheck.yml - promote: + build: runs-on: amd-runner-2204 needs: [setup, unit-tests, integration-tests, security-scan] if: needs.setup.outputs.version-changed == 'true' && needs.unit-tests.result == 'success' && needs.integration-tests.result == 'success' && needs.security-scan.result == 'success' From 983ed3fb8c98a0da9439a977fca75fc429b4c991 Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Fri, 5 Sep 2025 10:09:36 +0000 Subject: [PATCH 06/27] Update workflows to use test-security and add workflow_call --- .github/workflows/govulncheck.yml | 18 - .github/workflows/release.yml | 2 +- .github/workflows/test-e2e.yml | 597 +++++++++++++++--------------- .github/workflows/test-unit.yml | 69 ++-- 4 files changed, 335 insertions(+), 351 deletions(-) delete mode 100644 .github/workflows/govulncheck.yml diff --git a/.github/workflows/govulncheck.yml b/.github/workflows/govulncheck.yml deleted file mode 100644 index 8c3833c9a..000000000 --- a/.github/workflows/govulncheck.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Go Vulnerability Check - -on: [push] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - govulncheck_job: - runs-on: ubuntu-latest - name: Run govulncheck - steps: - - id: govulncheck - uses: golang/govulncheck-action@v1 - with: - go-version-input: 1.25.0 - go-package: ./... diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e5e4d76d8..79fc91e07 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -163,7 +163,7 @@ jobs: security-scan: needs: setup - uses: ./.github/workflows/govulncheck.yml + uses: ./.github/workflows/test-security.yml build: runs-on: amd-runner-2204 diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index fbad3e3be..d4ff68f48 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -4,330 +4,331 @@ name: Bats E2E Tests on: - push: - branches: - - "**" - schedule: - # Run every 24 hours at 00:00 UTC - - cron: "0 0 * * *" - workflow_dispatch: {} + push: + branches: + - "**" + schedule: + # Run every 24 hours at 00:00 UTC + - cron: "0 0 * * *" + workflow_dispatch: {} + workflow_call: {} concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true env: - AGGKIT_REPORT_CHANNEL: "C092K6Z0EUT" + AGGKIT_REPORT_CHANNEL: "C092K6Z0EUT" permissions: - packages: write - id-token: write - contents: read + packages: write + id-token: write + contents: read jobs: - get-kurtosis-cdk-commit: - name: Get Kurtosis CDK Commit - runs-on: ubuntu-latest - outputs: - kurtosis-commit: ${{ steps.get-commit.outputs.commit }} - steps: - - name: Get kurtosis-cdk commit based on trigger - id: get-commit - run: | - if [[ "${{ github.event_name }}" == "schedule" ]]; then - # For scheduled runs, get the latest commit - COMMIT="" - for i in {1..3}; do - COMMIT=$(curl -s https://api.github.com/repos/0xPolygon/kurtosis-cdk/commits/main | jq -r '.sha') - if [[ -n "$COMMIT" && "$COMMIT" != "null" ]]; then - echo "Using latest kurtosis-cdk commit: ${COMMIT}" - break - else - echo "Attempt $i: Failed to fetch commit, retrying..." - sleep 2 - fi - done + get-kurtosis-cdk-commit: + name: Get Kurtosis CDK Commit + runs-on: ubuntu-latest + outputs: + kurtosis-commit: ${{ steps.get-commit.outputs.commit }} + steps: + - name: Get kurtosis-cdk commit based on trigger + id: get-commit + run: | + if [[ "${{ github.event_name }}" == "schedule" ]]; then + # For scheduled runs, get the latest commit + COMMIT="" + for i in {1..3}; do + COMMIT=$(curl -s https://api.github.com/repos/0xPolygon/kurtosis-cdk/commits/main | jq -r '.sha') + if [[ -n "$COMMIT" && "$COMMIT" != "null" ]]; then + echo "Using latest kurtosis-cdk commit: ${COMMIT}" + break + else + echo "Attempt $i: Failed to fetch commit, retrying..." + sleep 2 + fi + done - if [[ -z "$COMMIT" || "$COMMIT" == "null" ]]; then - echo "Error: Failed to fetch kurtosis-cdk commit after 3 attempts" - exit 1 - fi - else - # For push/workflow_dispatch, use the fixed commit - COMMIT="f84ec739ff66d09caa584e887edc7942dc9a1a9a" - echo "Using fixed kurtosis-cdk commit: ${COMMIT}" - fi - echo "commit=${COMMIT}" >> $GITHUB_OUTPUT + if [[ -z "$COMMIT" || "$COMMIT" == "null" ]]; then + echo "Error: Failed to fetch kurtosis-cdk commit after 3 attempts" + exit 1 + fi + else + # For push/workflow_dispatch, use the fixed commit + COMMIT="f84ec739ff66d09caa584e887edc7942dc9a1a9a" + echo "Using fixed kurtosis-cdk commit: ${COMMIT}" + fi + echo "commit=${COMMIT}" >> $GITHUB_OUTPUT - build-aggkit-image: - uses: ./.github/workflows/build-aggkit-image.yml - with: - go-version: 1.25.x - docker-image-name: aggkit + build-aggkit-image: + uses: ./.github/workflows/build-aggkit-image.yml + with: + go-version: 1.25.x + docker-image-name: aggkit - read-aggkit-args: - name: Read aggkit args - runs-on: ubuntu-latest - outputs: - # single l2 network (op-succinct) - kurtosis-cdk-args-single-op-succinct: ${{ steps.read-args.outputs.op_succinct_args }} - # single l2 network (op-succinct with aggoracle committee) - kurtosis-cdk-args-single-op-succinct-aggoracle-committee: ${{ steps.read-args.outputs.op_succinct_aggoracle_committee_args }} - # single l2 network (fork 12, pessimistic) - kurtosis-cdk-args-single-fork12-pessimistic: ${{ steps.read-args.outputs.fork12_pessimistic_args }} - # single l2 network (fork 12, global index pp old contracts) - kurtosis-cdk-args-single-fork12-global-index-pp-old-contracts: ${{ steps.read-args.outputs.fork12_global_index_pp_old_contracts_args }} - # multi l2 networks - kurtosis-cdk-args-1: ${{ steps.read-args.outputs.kurtosis-cdk-args-1 }} - kurtosis-cdk-args-2: ${{ steps.read-args.outputs.kurtosis-cdk-args-2 }} - kurtosis-cdk-args-3: ${{ steps.read-args.outputs.kurtosis-cdk-args-3 }} - kurtosis-cdk-args-4: ${{ steps.read-args.outputs.kurtosis-cdk-args-4 }} - kurtosis-cdk-args-5: ${{ steps.read-args.outputs.kurtosis-cdk-args-5 }} - steps: - - name: Checkout - uses: actions/checkout@v5 + read-aggkit-args: + name: Read aggkit args + runs-on: ubuntu-latest + outputs: + # single l2 network (op-succinct) + kurtosis-cdk-args-single-op-succinct: ${{ steps.read-args.outputs.op_succinct_args }} + # single l2 network (op-succinct with aggoracle committee) + kurtosis-cdk-args-single-op-succinct-aggoracle-committee: ${{ steps.read-args.outputs.op_succinct_aggoracle_committee_args }} + # single l2 network (fork 12, pessimistic) + kurtosis-cdk-args-single-fork12-pessimistic: ${{ steps.read-args.outputs.fork12_pessimistic_args }} + # single l2 network (fork 12, global index pp old contracts) + kurtosis-cdk-args-single-fork12-global-index-pp-old-contracts: ${{ steps.read-args.outputs.fork12_global_index_pp_old_contracts_args }} + # multi l2 networks + kurtosis-cdk-args-1: ${{ steps.read-args.outputs.kurtosis-cdk-args-1 }} + kurtosis-cdk-args-2: ${{ steps.read-args.outputs.kurtosis-cdk-args-2 }} + kurtosis-cdk-args-3: ${{ steps.read-args.outputs.kurtosis-cdk-args-3 }} + kurtosis-cdk-args-4: ${{ steps.read-args.outputs.kurtosis-cdk-args-4 }} + kurtosis-cdk-args-5: ${{ steps.read-args.outputs.kurtosis-cdk-args-5 }} + steps: + - name: Checkout + uses: actions/checkout@v5 - - name: Read kurtosis-cdk-args from file - id: read-args - run: | - # single l2 network (fork 12, op-succinct) - CONTENT=$(cat ./.github/test_e2e_single_chain_op_succinct_args.json | jq -c .) - echo "op_succinct_args=${CONTENT}" >> $GITHUB_OUTPUT - # single l2 network (fork 12, op-succinct with aggoracle committee) - CONTENT=$(cat ./.github/test_e2e_single_chain_op_succinct_aggoracle_committee_args.json | jq -c .) - echo "op_succinct_aggoracle_committee_args=${CONTENT}" >> $GITHUB_OUTPUT - # single l2 network (fork 12, pessimistic) - CONTENT=$(jq -s '.[0] * .[1]' ./.github/test_e2e_cdk_args_base.json ./.github/test_e2e_gas_token_enabled_args.json | jq -c .) - echo "fork12_pessimistic_args=${CONTENT}" >> $GITHUB_OUTPUT - # single l2 network (fork 12, global index pp old contracts) - CONTENT=$(jq -s '.[0] * .[1]' ./.github/test_e2e_cdk_args_base.json ./.github/test_e2e_cdk_args_global_index_pp_old_contracts.json | jq -c .) - echo "fork12_global_index_pp_old_contracts_args=${CONTENT}" >> $GITHUB_OUTPUT - # multi l2 networks - CONTENT=$(cat ./.github/test_e2e_cdk_args_base.json | jq -c .) - echo "kurtosis-cdk-args-1=${CONTENT}" >> $GITHUB_OUTPUT - CONTENT=$(jq -s '.[0] * .[1]' ./.github/test_e2e_cdk_args_base.json ./.github/test_e2e_multi_chains_args_2.json | jq -c .) - echo "kurtosis-cdk-args-2=${CONTENT}" >> $GITHUB_OUTPUT - # Merge base_1 args with args_3 for kurtosis-cdk-args-3 - CONTENT=$(jq -s '.[0] * .[1]' ./.github/test_e2e_cdk_args_base.json ./.github/test_e2e_gas_token_enabled_args.json | jq -c .) - echo "kurtosis-cdk-args-3=${CONTENT}" >> $GITHUB_OUTPUT - # Merge base_2 args with args_4 for kurtosis-cdk-args-4 - CONTENT=$(jq -s '.[0] * .[1] * .[2]' ./.github/test_e2e_cdk_args_base.json ./.github/test_e2e_multi_chains_args_2.json ./.github/test_e2e_gas_token_enabled_args.json | jq -c .) - echo "kurtosis-cdk-args-4=${CONTENT}" >> $GITHUB_OUTPUT - # Merge base_2 args with args_5 for kurtosis-cdk-args-5 - CONTENT=$(jq -s '.[0] * .[1] * .[2]' ./.github/test_e2e_cdk_args_base.json ./.github/test_e2e_multi_chains_args_2.json ./.github/test_e2e_multi_chains_args_3.json | jq -c .) - echo "kurtosis-cdk-args-5=${CONTENT}" >> $GITHUB_OUTPUT + - name: Read kurtosis-cdk-args from file + id: read-args + run: | + # single l2 network (fork 12, op-succinct) + CONTENT=$(cat ./.github/test_e2e_single_chain_op_succinct_args.json | jq -c .) + echo "op_succinct_args=${CONTENT}" >> $GITHUB_OUTPUT + # single l2 network (fork 12, op-succinct with aggoracle committee) + CONTENT=$(cat ./.github/test_e2e_single_chain_op_succinct_aggoracle_committee_args.json | jq -c .) + echo "op_succinct_aggoracle_committee_args=${CONTENT}" >> $GITHUB_OUTPUT + # single l2 network (fork 12, pessimistic) + CONTENT=$(jq -s '.[0] * .[1]' ./.github/test_e2e_cdk_args_base.json ./.github/test_e2e_gas_token_enabled_args.json | jq -c .) + echo "fork12_pessimistic_args=${CONTENT}" >> $GITHUB_OUTPUT + # single l2 network (fork 12, global index pp old contracts) + CONTENT=$(jq -s '.[0] * .[1]' ./.github/test_e2e_cdk_args_base.json ./.github/test_e2e_cdk_args_global_index_pp_old_contracts.json | jq -c .) + echo "fork12_global_index_pp_old_contracts_args=${CONTENT}" >> $GITHUB_OUTPUT + # multi l2 networks + CONTENT=$(cat ./.github/test_e2e_cdk_args_base.json | jq -c .) + echo "kurtosis-cdk-args-1=${CONTENT}" >> $GITHUB_OUTPUT + CONTENT=$(jq -s '.[0] * .[1]' ./.github/test_e2e_cdk_args_base.json ./.github/test_e2e_multi_chains_args_2.json | jq -c .) + echo "kurtosis-cdk-args-2=${CONTENT}" >> $GITHUB_OUTPUT + # Merge base_1 args with args_3 for kurtosis-cdk-args-3 + CONTENT=$(jq -s '.[0] * .[1]' ./.github/test_e2e_cdk_args_base.json ./.github/test_e2e_gas_token_enabled_args.json | jq -c .) + echo "kurtosis-cdk-args-3=${CONTENT}" >> $GITHUB_OUTPUT + # Merge base_2 args with args_4 for kurtosis-cdk-args-4 + CONTENT=$(jq -s '.[0] * .[1] * .[2]' ./.github/test_e2e_cdk_args_base.json ./.github/test_e2e_multi_chains_args_2.json ./.github/test_e2e_gas_token_enabled_args.json | jq -c .) + echo "kurtosis-cdk-args-4=${CONTENT}" >> $GITHUB_OUTPUT + # Merge base_2 args with args_5 for kurtosis-cdk-args-5 + CONTENT=$(jq -s '.[0] * .[1] * .[2]' ./.github/test_e2e_cdk_args_base.json ./.github/test_e2e_multi_chains_args_2.json ./.github/test_e2e_multi_chains_args_3.json | jq -c .) + echo "kurtosis-cdk-args-5=${CONTENT}" >> $GITHUB_OUTPUT - build-tools: - name: Build aggsender find imported bridge tool - needs: - - build-aggkit-image - runs-on: amd-runner-2204 - steps: - - name: Checkout code - uses: actions/checkout@v5 - - name: Install Go - uses: actions/setup-go@v5 - with: - go-version: 1.25.x - - name: Build Aggsender Find Imported Bridge - run: make build-tools - - name: Upload Binary - uses: actions/upload-artifact@v4 - with: - name: aggsender_find_imported_bridge - path: ./target/aggsender_find_imported_bridge + build-tools: + name: Build aggsender find imported bridge tool + needs: + - build-aggkit-image + runs-on: amd-runner-2204 + steps: + - name: Checkout code + uses: actions/checkout@v5 + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: 1.25.x + - name: Build Aggsender Find Imported Bridge + run: make build-tools + - name: Upload Binary + uses: actions/upload-artifact@v4 + with: + name: aggsender_find_imported_bridge + path: ./target/aggsender_find_imported_bridge - test-single-l2-network-fork12-pessimistic: - name: Single L2 chain tests (pessimistic) - needs: - - build-aggkit-image - - read-aggkit-args - - get-kurtosis-cdk-commit - uses: agglayer/e2e/.github/workflows/aggkit-e2e-single-chain.yml@b89e67587388ddf57c992b9113b28ef1d90ee8ef - secrets: inherit - with: - kurtosis-cdk-ref: ${{ needs.get-kurtosis-cdk-commit.outputs.kurtosis-commit }} - agglayer-e2e-ref: b89e67587388ddf57c992b9113b28ef1d90ee8ef - kurtosis-cdk-enclave-name: aggkit - kurtosis-cdk-args: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-single-fork12-pessimistic }} - test-name: "test-single-l2-network-fork12-pessimistic" - event-name: ${{ github.event_name }} + test-single-l2-network-fork12-pessimistic: + name: Single L2 chain tests (pessimistic) + needs: + - build-aggkit-image + - read-aggkit-args + - get-kurtosis-cdk-commit + uses: agglayer/e2e/.github/workflows/aggkit-e2e-single-chain.yml@b89e67587388ddf57c992b9113b28ef1d90ee8ef + secrets: inherit + with: + kurtosis-cdk-ref: ${{ needs.get-kurtosis-cdk-commit.outputs.kurtosis-commit }} + agglayer-e2e-ref: b89e67587388ddf57c992b9113b28ef1d90ee8ef + kurtosis-cdk-enclave-name: aggkit + kurtosis-cdk-args: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-single-fork12-pessimistic }} + test-name: "test-single-l2-network-fork12-pessimistic" + event-name: ${{ github.event_name }} - check-single-l2-network-fork12-pessimistic-tests-result: - name: Check results for single l2 network (pessimistic) - needs: - - test-single-l2-network-fork12-pessimistic - runs-on: ubuntu-latest - steps: - - run: exit 1 - if: ${{ contains(fromJSON('["failure", "cancelled"]'), needs.test-single-l2-network-fork12-pessimistic.result) }} + check-single-l2-network-fork12-pessimistic-tests-result: + name: Check results for single l2 network (pessimistic) + needs: + - test-single-l2-network-fork12-pessimistic + runs-on: ubuntu-latest + steps: + - run: exit 1 + if: ${{ contains(fromJSON('["failure", "cancelled"]'), needs.test-single-l2-network-fork12-pessimistic.result) }} - test-single-l2-network-fork12-global-index-pp-old-contracts: - name: Single L2 chain tests (global index pp old contracts) - needs: - - build-aggkit-image - - build-tools - - read-aggkit-args - - get-kurtosis-cdk-commit - uses: agglayer/e2e/.github/workflows/aggkit-e2e-single-chain.yml@b89e67587388ddf57c992b9113b28ef1d90ee8ef - secrets: inherit - if: always() && github.event_name == 'schedule' && github.ref == 'refs/heads/develop' - with: - kurtosis-cdk-ref: ${{ needs.get-kurtosis-cdk-commit.outputs.kurtosis-commit }} - agglayer-e2e-ref: b89e67587388ddf57c992b9113b28ef1d90ee8ef - kurtosis-cdk-enclave-name: aggkit - kurtosis-cdk-args: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-single-fork12-global-index-pp-old-contracts }} - test-name: "test-single-l2-network-fork12-global-index-pp-old-contracts" - aggsender-find-imported-bridge-artifact: aggsender_find_imported_bridge - event-name: ${{ github.event_name }} + test-single-l2-network-fork12-global-index-pp-old-contracts: + name: Single L2 chain tests (global index pp old contracts) + needs: + - build-aggkit-image + - build-tools + - read-aggkit-args + - get-kurtosis-cdk-commit + uses: agglayer/e2e/.github/workflows/aggkit-e2e-single-chain.yml@b89e67587388ddf57c992b9113b28ef1d90ee8ef + secrets: inherit + if: always() && github.event_name == 'schedule' && github.ref == 'refs/heads/develop' + with: + kurtosis-cdk-ref: ${{ needs.get-kurtosis-cdk-commit.outputs.kurtosis-commit }} + agglayer-e2e-ref: b89e67587388ddf57c992b9113b28ef1d90ee8ef + kurtosis-cdk-enclave-name: aggkit + kurtosis-cdk-args: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-single-fork12-global-index-pp-old-contracts }} + test-name: "test-single-l2-network-fork12-global-index-pp-old-contracts" + aggsender-find-imported-bridge-artifact: aggsender_find_imported_bridge + event-name: ${{ github.event_name }} - check-single-l2-network-fork12-global-index-pp-old-contracts-tests-result: - name: Check results for single l2 network (global index pp old contracts) - needs: - - test-single-l2-network-fork12-global-index-pp-old-contracts - if: always() && github.event_name == 'schedule' && github.ref == 'refs/heads/develop' - runs-on: ubuntu-latest - steps: - - run: exit 1 - if: ${{ contains(fromJSON('["failure", "cancelled"]'), needs.test-single-l2-network-fork12-global-index-pp-old-contracts.result) }} + check-single-l2-network-fork12-global-index-pp-old-contracts-tests-result: + name: Check results for single l2 network (global index pp old contracts) + needs: + - test-single-l2-network-fork12-global-index-pp-old-contracts + if: always() && github.event_name == 'schedule' && github.ref == 'refs/heads/develop' + runs-on: ubuntu-latest + steps: + - run: exit 1 + if: ${{ contains(fromJSON('["failure", "cancelled"]'), needs.test-single-l2-network-fork12-global-index-pp-old-contracts.result) }} - test-single-l2-network-op-succinct: - name: Single L2 chain tests (op-succinct) - needs: - - build-aggkit-image - - read-aggkit-args - - get-kurtosis-cdk-commit - uses: agglayer/e2e/.github/workflows/aggkit-e2e-single-chain.yml@b89e67587388ddf57c992b9113b28ef1d90ee8ef - secrets: inherit - with: - kurtosis-cdk-ref: ${{ needs.get-kurtosis-cdk-commit.outputs.kurtosis-commit }} - agglayer-e2e-ref: b89e67587388ddf57c992b9113b28ef1d90ee8ef - kurtosis-cdk-enclave-name: op - kurtosis-cdk-args: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-single-op-succinct }} - test-name: "test-single-l2-network-op-succinct" - event-name: ${{ github.event_name }} + test-single-l2-network-op-succinct: + name: Single L2 chain tests (op-succinct) + needs: + - build-aggkit-image + - read-aggkit-args + - get-kurtosis-cdk-commit + uses: agglayer/e2e/.github/workflows/aggkit-e2e-single-chain.yml@b89e67587388ddf57c992b9113b28ef1d90ee8ef + secrets: inherit + with: + kurtosis-cdk-ref: ${{ needs.get-kurtosis-cdk-commit.outputs.kurtosis-commit }} + agglayer-e2e-ref: b89e67587388ddf57c992b9113b28ef1d90ee8ef + kurtosis-cdk-enclave-name: op + kurtosis-cdk-args: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-single-op-succinct }} + test-name: "test-single-l2-network-op-succinct" + event-name: ${{ github.event_name }} - check-single-network-op-succinct-tests-result: - name: Check results for single l2 network (op-succinct) - needs: - - test-single-l2-network-op-succinct - runs-on: ubuntu-latest - steps: - - run: exit 1 - if: ${{ contains(fromJSON('["failure", "cancelled"]'), needs.test-single-l2-network-op-succinct.result) }} + check-single-network-op-succinct-tests-result: + name: Check results for single l2 network (op-succinct) + needs: + - test-single-l2-network-op-succinct + runs-on: ubuntu-latest + steps: + - run: exit 1 + if: ${{ contains(fromJSON('["failure", "cancelled"]'), needs.test-single-l2-network-op-succinct.result) }} - test-single-l2-network-op-succinct-aggoracle-committee: - name: Single L2 chain tests (op-succinct with aggoracle committee) - needs: - - build-aggkit-image - - read-aggkit-args - - get-kurtosis-cdk-commit - uses: agglayer/e2e/.github/workflows/aggkit-e2e-single-chain.yml@b89e67587388ddf57c992b9113b28ef1d90ee8ef - secrets: inherit - if: always() && github.event_name == 'schedule' && github.ref == 'refs/heads/develop' - with: - kurtosis-cdk-ref: ${{ needs.get-kurtosis-cdk-commit.outputs.kurtosis-commit }} - agglayer-e2e-ref: b89e67587388ddf57c992b9113b28ef1d90ee8ef - kurtosis-cdk-enclave-name: op - kurtosis-cdk-args: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-single-op-succinct-aggoracle-committee }} - test-name: "test-single-l2-network-op-succinct-aggoracle-committee" - event-name: ${{ github.event_name }} + test-single-l2-network-op-succinct-aggoracle-committee: + name: Single L2 chain tests (op-succinct with aggoracle committee) + needs: + - build-aggkit-image + - read-aggkit-args + - get-kurtosis-cdk-commit + uses: agglayer/e2e/.github/workflows/aggkit-e2e-single-chain.yml@b89e67587388ddf57c992b9113b28ef1d90ee8ef + secrets: inherit + if: always() && github.event_name == 'schedule' && github.ref == 'refs/heads/develop' + with: + kurtosis-cdk-ref: ${{ needs.get-kurtosis-cdk-commit.outputs.kurtosis-commit }} + agglayer-e2e-ref: b89e67587388ddf57c992b9113b28ef1d90ee8ef + kurtosis-cdk-enclave-name: op + kurtosis-cdk-args: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-single-op-succinct-aggoracle-committee }} + test-name: "test-single-l2-network-op-succinct-aggoracle-committee" + event-name: ${{ github.event_name }} - check-single-l2-network-op-succinct-aggoracle-committee-tests-result: - name: Check results for single l2 network (op-succinct with aggoracle committee) - needs: - - test-single-l2-network-op-succinct-aggoracle-committee - if: always() && github.event_name == 'schedule' && github.ref == 'refs/heads/develop' - runs-on: ubuntu-latest - steps: - - run: exit 1 - if: ${{ contains(fromJSON('["failure", "cancelled"]'), needs.test-single-l2-network-op-succinct-aggoracle-committee.result) }} + check-single-l2-network-op-succinct-aggoracle-committee-tests-result: + name: Check results for single l2 network (op-succinct with aggoracle committee) + needs: + - test-single-l2-network-op-succinct-aggoracle-committee + if: always() && github.event_name == 'schedule' && github.ref == 'refs/heads/develop' + runs-on: ubuntu-latest + steps: + - run: exit 1 + if: ${{ contains(fromJSON('["failure", "cancelled"]'), needs.test-single-l2-network-op-succinct-aggoracle-committee.result) }} - test-multi-l2-networks-2-chains: - name: Multi chains E2E test (2 chains) - needs: - - build-aggkit-image - - build-tools - - read-aggkit-args - - get-kurtosis-cdk-commit - uses: agglayer/e2e/.github/workflows/aggkit-e2e-multi-chains.yml@b89e67587388ddf57c992b9113b28ef1d90ee8ef - secrets: inherit - with: - kurtosis-cdk-ref: ${{ needs.get-kurtosis-cdk-commit.outputs.kurtosis-commit }} - agglayer-e2e-ref: b89e67587388ddf57c992b9113b28ef1d90ee8ef - kurtosis-cdk-enclave-name: aggkit - aggsender-find-imported-bridge-artifact: aggsender_find_imported_bridge - kurtosis-cdk-args-1: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-1 }} - kurtosis-cdk-args-2: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-2 }} + test-multi-l2-networks-2-chains: + name: Multi chains E2E test (2 chains) + needs: + - build-aggkit-image + - build-tools + - read-aggkit-args + - get-kurtosis-cdk-commit + uses: agglayer/e2e/.github/workflows/aggkit-e2e-multi-chains.yml@b89e67587388ddf57c992b9113b28ef1d90ee8ef + secrets: inherit + with: + kurtosis-cdk-ref: ${{ needs.get-kurtosis-cdk-commit.outputs.kurtosis-commit }} + agglayer-e2e-ref: b89e67587388ddf57c992b9113b28ef1d90ee8ef + kurtosis-cdk-enclave-name: aggkit + aggsender-find-imported-bridge-artifact: aggsender_find_imported_bridge + kurtosis-cdk-args-1: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-1 }} + kurtosis-cdk-args-2: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-2 }} - check-multi-l2-networks-2-chains-tests-result: - name: Check results for multi l2 networks (2 chains) - needs: - - test-multi-l2-networks-2-chains - runs-on: ubuntu-latest - steps: - - run: exit 1 - if: ${{ contains(fromJSON('["failure", "cancelled"]'), needs.test-multi-l2-networks-2-chains.result) }} + check-multi-l2-networks-2-chains-tests-result: + name: Check results for multi l2 networks (2 chains) + needs: + - test-multi-l2-networks-2-chains + runs-on: ubuntu-latest + steps: + - run: exit 1 + if: ${{ contains(fromJSON('["failure", "cancelled"]'), needs.test-multi-l2-networks-2-chains.result) }} - test-multi-l2-networks-3-chains: - name: Multi chains E2E test (3 chains) - needs: - - build-aggkit-image - - build-tools - - read-aggkit-args - - get-kurtosis-cdk-commit - uses: agglayer/e2e/.github/workflows/aggkit-e2e-multi-chains.yml@b89e67587388ddf57c992b9113b28ef1d90ee8ef - secrets: inherit - if: always() && github.event_name == 'schedule' && github.ref == 'refs/heads/develop' - with: - kurtosis-cdk-ref: ${{ needs.get-kurtosis-cdk-commit.outputs.kurtosis-commit }} - agglayer-e2e-ref: b89e67587388ddf57c992b9113b28ef1d90ee8ef - kurtosis-cdk-enclave-name: aggkit - aggsender-find-imported-bridge-artifact: aggsender_find_imported_bridge - kurtosis-cdk-args-1: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-3 }} - kurtosis-cdk-args-2: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-4 }} - kurtosis-cdk-args-3: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-5 }} - number-of-chains: 3 + test-multi-l2-networks-3-chains: + name: Multi chains E2E test (3 chains) + needs: + - build-aggkit-image + - build-tools + - read-aggkit-args + - get-kurtosis-cdk-commit + uses: agglayer/e2e/.github/workflows/aggkit-e2e-multi-chains.yml@b89e67587388ddf57c992b9113b28ef1d90ee8ef + secrets: inherit + if: always() && github.event_name == 'schedule' && github.ref == 'refs/heads/develop' + with: + kurtosis-cdk-ref: ${{ needs.get-kurtosis-cdk-commit.outputs.kurtosis-commit }} + agglayer-e2e-ref: b89e67587388ddf57c992b9113b28ef1d90ee8ef + kurtosis-cdk-enclave-name: aggkit + aggsender-find-imported-bridge-artifact: aggsender_find_imported_bridge + kurtosis-cdk-args-1: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-3 }} + kurtosis-cdk-args-2: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-4 }} + kurtosis-cdk-args-3: ${{ needs.read-aggkit-args.outputs.kurtosis-cdk-args-5 }} + number-of-chains: 3 - check-multi-l2-networks-3-chains-tests-result: - name: Check results for multi l2 networks (3 chains) - needs: - - test-multi-l2-networks-3-chains - runs-on: ubuntu-latest - if: always() && github.event_name == 'schedule' && github.ref == 'refs/heads/develop' - steps: - - run: exit 1 - if: ${{ contains(fromJSON('["failure", "cancelled"]'), needs.test-multi-l2-networks-3-chains.result) }} + check-multi-l2-networks-3-chains-tests-result: + name: Check results for multi l2 networks (3 chains) + needs: + - test-multi-l2-networks-3-chains + runs-on: ubuntu-latest + if: always() && github.event_name == 'schedule' && github.ref == 'refs/heads/develop' + steps: + - run: exit 1 + if: ${{ contains(fromJSON('["failure", "cancelled"]'), needs.test-multi-l2-networks-3-chains.result) }} - notify-slack: - name: Notify Slack - needs: - - test-single-l2-network-fork12-pessimistic - - test-single-l2-network-op-succinct - - test-single-l2-network-op-succinct-aggoracle-committee - - test-multi-l2-networks-2-chains - - test-multi-l2-networks-3-chains - - test-single-l2-network-fork12-global-index-pp-old-contracts - - get-kurtosis-cdk-commit - runs-on: ubuntu-latest - if: always() && github.event_name == 'schedule' && github.ref == 'refs/heads/develop' - steps: - - name: Send Slack notification - uses: agglayer/gha-notify-generic@v1 - with: - slack-bot-token: ${{ secrets.SLACK_APP_TOKEN_AGGLAYER_NOTIFY_GENERIC }} - channel-id: ${{ env.AGGKIT_REPORT_CHANNEL }} - message: | - Daily E2E Tests Report + notify-slack: + name: Notify Slack + needs: + - test-single-l2-network-fork12-pessimistic + - test-single-l2-network-op-succinct + - test-single-l2-network-op-succinct-aggoracle-committee + - test-multi-l2-networks-2-chains + - test-multi-l2-networks-3-chains + - test-single-l2-network-fork12-global-index-pp-old-contracts + - get-kurtosis-cdk-commit + runs-on: ubuntu-latest + if: always() && github.event_name == 'schedule' && github.ref == 'refs/heads/develop' + steps: + - name: Send Slack notification + uses: agglayer/gha-notify-generic@v1 + with: + slack-bot-token: ${{ secrets.SLACK_APP_TOKEN_AGGLAYER_NOTIFY_GENERIC }} + channel-id: ${{ env.AGGKIT_REPORT_CHANNEL }} + message: | + Daily E2E Tests Report - Kurtosis CDK Commit: `${{ needs.get-kurtosis-cdk-commit.outputs.kurtosis-commit }}` + Kurtosis CDK Commit: `${{ needs.get-kurtosis-cdk-commit.outputs.kurtosis-commit }}` - Test Results: - โ€ข Single L2 (pessimistic): ${{ needs.test-single-l2-network-fork12-pessimistic.result == 'success' && '๐ŸŸข' || '๐Ÿ”ด' }} - โ€ข Single L2 (op-succinct): ${{ needs.test-single-l2-network-op-succinct.result == 'success' && '๐ŸŸข' || '๐Ÿ”ด' }} - โ€ข Single L2 (op-succinct with aggoracle committee): ${{ needs.test-single-l2-network-op-succinct-aggoracle-committee.result == 'success' && '๐ŸŸข' || '๐Ÿ”ด' }} - โ€ข Multi L2 (2 chains): ${{ needs.test-multi-l2-networks-2-chains.result == 'success' && '๐ŸŸข' || '๐Ÿ”ด' }} - โ€ข Multi L2 (3 chains): ${{ needs.test-multi-l2-networks-3-chains.result == 'success' && '๐ŸŸข' || '๐Ÿ”ด' }} - โ€ข Single L2 (global index pp old contracts): ${{ needs.test-single-l2-network-fork12-global-index-pp-old-contracts.result == 'success' && '๐ŸŸข' || '๐Ÿ”ด' }} + Test Results: + โ€ข Single L2 (pessimistic): ${{ needs.test-single-l2-network-fork12-pessimistic.result == 'success' && '๐ŸŸข' || '๐Ÿ”ด' }} + โ€ข Single L2 (op-succinct): ${{ needs.test-single-l2-network-op-succinct.result == 'success' && '๐ŸŸข' || '๐Ÿ”ด' }} + โ€ข Single L2 (op-succinct with aggoracle committee): ${{ needs.test-single-l2-network-op-succinct-aggoracle-committee.result == 'success' && '๐ŸŸข' || '๐Ÿ”ด' }} + โ€ข Multi L2 (2 chains): ${{ needs.test-multi-l2-networks-2-chains.result == 'success' && '๐ŸŸข' || '๐Ÿ”ด' }} + โ€ข Multi L2 (3 chains): ${{ needs.test-multi-l2-networks-3-chains.result == 'success' && '๐ŸŸข' || '๐Ÿ”ด' }} + โ€ข Single L2 (global index pp old contracts): ${{ needs.test-single-l2-network-fork12-global-index-pp-old-contracts.result == 'success' && '๐ŸŸข' || '๐Ÿ”ด' }} - <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Workflow> + <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Workflow> diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml index 1990c3a4a..cc9f41e0a 100644 --- a/.github/workflows/test-unit.yml +++ b/.github/workflows/test-unit.yml @@ -1,44 +1,45 @@ name: Test Unit and SonarCloud analysis on: - push: - branches: - - main - - develop - - 'release/**' - pull_request: - workflow_dispatch: {} + push: + branches: + - main + - develop + - "release/**" + pull_request: + workflow_dispatch: {} + workflow_call: {} concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: - test-unit: - strategy: - fail-fast: false - matrix: - go-version: [1.25.0] - goarch: ["amd64"] - runs-on: amd-runner-2204 - steps: - - name: Checkout code - uses: actions/checkout@v5 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + test-unit: + strategy: + fail-fast: false + matrix: + go-version: [1.25.0] + goarch: ["amd64"] + runs-on: amd-runner-2204 + steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - name: Install Go - uses: actions/setup-go@v5 - with: - go-version: ${{ matrix.go-version }} - env: - GOARCH: ${{ matrix.goarch }} + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: ${{ matrix.go-version }} + env: + GOARCH: ${{ matrix.goarch }} - - name: Test - run: make test-unit + - name: Test + run: make test-unit - - name: SonarQube Scan - uses: SonarSource/sonarqube-scan-action@v4.2.1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + - name: SonarQube Scan + uses: SonarSource/sonarqube-scan-action@v4.2.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} From d4a88a3efa6615fa7861ca5f6aa28b1f0c4c890c Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Fri, 5 Sep 2025 10:10:17 +0000 Subject: [PATCH 07/27] Add GitHub Actions workflow for Go vulnerability checks --- .github/workflows/test-security.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/test-security.yml diff --git a/.github/workflows/test-security.yml b/.github/workflows/test-security.yml new file mode 100644 index 000000000..f9beaceec --- /dev/null +++ b/.github/workflows/test-security.yml @@ -0,0 +1,20 @@ +name: Go Vulnerability Check + +on: + push: {} + workflow_call: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + govulncheck_job: + runs-on: ubuntu-latest + name: Run govulncheck + steps: + - id: govulncheck + uses: golang/govulncheck-action@v1 + with: + go-version-input: 1.25.0 + go-package: ./... From c50c1d9d81b8e8c2153ed197294a6866e61dd0ed Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Fri, 5 Sep 2025 10:13:50 +0000 Subject: [PATCH 08/27] Add id-token write permission to release workflow --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 79fc91e07..813316570 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,6 +15,7 @@ concurrency: permissions: contents: write packages: write + id-token: write env: REGISTRY: ghcr.io From 48c0cdddff7a0cb76d5131bac6d41d86144eddbf Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Fri, 5 Sep 2025 10:44:34 +0000 Subject: [PATCH 09/27] Comment out integration and security test jobs in release workflow --- .github/workflows/release.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 813316570..a916b627e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -158,17 +158,17 @@ jobs: needs: setup uses: ./.github/workflows/test-unit.yml - integration-tests: - needs: setup - uses: ./.github/workflows/test-e2e.yml + # integration-tests: + # needs: setup + # uses: ./.github/workflows/test-e2e.yml - security-scan: - needs: setup - uses: ./.github/workflows/test-security.yml + # security-scan: + # needs: setup + # uses: ./.github/workflows/test-security.yml build: runs-on: amd-runner-2204 - needs: [setup, unit-tests, integration-tests, security-scan] + needs: [setup, unit-tests] if: needs.setup.outputs.version-changed == 'true' && needs.unit-tests.result == 'success' && needs.integration-tests.result == 'success' && needs.security-scan.result == 'success' strategy: fail-fast: false From 61042998e46cdfcedc8da1dc4fa30f2b13b2daab Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Fri, 5 Sep 2025 13:07:51 +0000 Subject: [PATCH 10/27] Move TEST_PLACEHOLDER_START after badge in release workflow --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a916b627e..71b0dbac6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -99,8 +99,8 @@ jobs: if [ -n "$TEST_LINES" ]; then # Create replacement content cat > replacement_content.tmp << EOF - [![Release](https://github.com/agglayer/aggkit/actions/workflows/release.yml/badge.svg?branch=$TAG_VERSION)](https://github.com/agglayer/aggkit/actions/workflows/release.yml) + $TEST_LINES EOF From aff6bd7b7f71390a3c769471944730cbe033a2ff Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Fri, 5 Sep 2025 13:11:21 +0000 Subject: [PATCH 11/27] Inherit secrets in unit test workflow --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 71b0dbac6..809c9d4ce 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -157,6 +157,7 @@ jobs: unit-tests: needs: setup uses: ./.github/workflows/test-unit.yml + secrets: inherit # integration-tests: # needs: setup From 603c4078af093c2cd12514c5d542be8aee4d34a7 Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Fri, 5 Sep 2025 13:23:28 +0000 Subject: [PATCH 12/27] Add release workflow badge to release notes template --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 809c9d4ce..baea18aae 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -84,6 +84,7 @@ jobs: - [Brief description of new features] ## โœ… Testing & Validation + [![Release](https://github.com/agglayer/aggkit/actions/workflows/release.yml/badge.svg?branch=$TAG_VERSION)](https://github.com/agglayer/aggkit/actions/workflows/release.yml) @@ -99,7 +100,6 @@ jobs: if [ -n "$TEST_LINES" ]; then # Create replacement content cat > replacement_content.tmp << EOF - [![Release](https://github.com/agglayer/aggkit/actions/workflows/release.yml/badge.svg?branch=$TAG_VERSION)](https://github.com/agglayer/aggkit/actions/workflows/release.yml) $TEST_LINES From 517b872dc08f7ec9bff6618de19fef22e31d9a0f Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Fri, 5 Sep 2025 14:57:37 +0000 Subject: [PATCH 13/27] Remove test placeholder replacement logic from release workflow --- .github/workflows/release.yml | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index baea18aae..e40469e10 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -85,36 +85,12 @@ jobs: ## โœ… Testing & Validation [![Release](https://github.com/agglayer/aggkit/actions/workflows/release.yml/badge.svg?branch=$TAG_VERSION)](https://github.com/agglayer/aggkit/actions/workflows/release.yml) - - ## ๐Ÿ“ฆ Full Changelog See the [full changelog]($CHANGELOG_LINK) for detailed changes. EOF } - # Always replace the test placeholder with dynamic test list (whether git-cliff succeeds or fails) - TEST_LINES=$(echo '${{ env.TEST_CONFIG }}' | jq -r '.[] | "- **" + .name + "**: [Running...](#)"') - - # Replace placeholder in release notes - if [ -n "$TEST_LINES" ]; then - # Create replacement content - cat > replacement_content.tmp << EOF - - $TEST_LINES - - EOF - - # Replace placeholder section - sed -i '//,//d' release_notes.md - sed -i '/## โœ… Testing & Validation/r replacement_content.tmp' release_notes.md - - # Clean up - rm -f replacement_content.tmp - else - echo "โš ๏ธ No test configuration found, using default placeholder" - fi - echo "โœ… Release notes generated" # Step 3: Create pre-release From 1d2e590987f0018846903be7ed5454b228def659 Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Fri, 5 Sep 2025 15:16:05 +0000 Subject: [PATCH 14/27] Add release workflow badge to testing section in cliff.toml --- cliff.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/cliff.toml b/cliff.toml index d2f66a74b..229b89018 100644 --- a/cliff.toml +++ b/cliff.toml @@ -30,6 +30,7 @@ body = """ - [Brief description of new features] ## โœ… Testing & Validation +[![Release](https://github.com/agglayer/aggkit/actions/workflows/release.yml/badge.svg?branch=$TAG_VERSION)](https://github.com/agglayer/aggkit/actions/workflows/release.yml) From e9dfac548c9555d826ad44fe7b0eb43638cf5b76 Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Fri, 5 Sep 2025 15:29:47 +0000 Subject: [PATCH 15/27] Remove fallback release notes logic and fix badge version variable --- .github/workflows/release.yml | 26 +------------------------- cliff.toml | 2 +- 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e40469e10..f1ec96d8c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -66,31 +66,7 @@ jobs: echo "๐Ÿ“ Generating release notes for $TAG_VERSION..." # Generate release notes with git-cliff - git-cliff --latest --output release_notes.md || { - echo "โš ๏ธ git-cliff failed, creating fallback release notes" - - # Get previous tag for fallback - PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") - - # Create fallback content with proper tag handling - if [ -n "$PREVIOUS_TAG" ] && [ "$PREVIOUS_TAG" != "$TAG_VERSION" ]; then - CHANGELOG_LINK="https://github.com/${{ github.repository }}/compare/$PREVIOUS_TAG...$TAG_VERSION" - else - CHANGELOG_LINK="https://github.com/${{ github.repository }}/commits/$TAG_VERSION" - fi - - cat > release_notes.md << EOF - ## ๐Ÿš€ What's New - - [Brief description of new features] - - ## โœ… Testing & Validation - [![Release](https://github.com/agglayer/aggkit/actions/workflows/release.yml/badge.svg?branch=$TAG_VERSION)](https://github.com/agglayer/aggkit/actions/workflows/release.yml) - - ## ๐Ÿ“ฆ Full Changelog - See the [full changelog]($CHANGELOG_LINK) for detailed changes. - EOF - } - + git-cliff --latest --output release_notes.md echo "โœ… Release notes generated" # Step 3: Create pre-release diff --git a/cliff.toml b/cliff.toml index 229b89018..ddb80361b 100644 --- a/cliff.toml +++ b/cliff.toml @@ -30,7 +30,7 @@ body = """ - [Brief description of new features] ## โœ… Testing & Validation -[![Release](https://github.com/agglayer/aggkit/actions/workflows/release.yml/badge.svg?branch=$TAG_VERSION)](https://github.com/agglayer/aggkit/actions/workflows/release.yml) +[![Release](https://github.com/agglayer/aggkit/actions/workflows/release.yml/badge.svg?branch={{ version }})](https://github.com/agglayer/aggkit/actions/workflows/release.yml) From 5fcc514a4bee013b17a1a66dc8198cce97db729b Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Mon, 8 Sep 2025 09:56:58 +0000 Subject: [PATCH 16/27] Remove release template markdown file --- .github/RELEASE_TEMPLATE.md | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 .github/RELEASE_TEMPLATE.md diff --git a/.github/RELEASE_TEMPLATE.md b/.github/RELEASE_TEMPLATE.md deleted file mode 100644 index 2269db344..000000000 --- a/.github/RELEASE_TEMPLATE.md +++ /dev/null @@ -1,16 +0,0 @@ -## ๐Ÿš€ What's New -- [Brief description of new features] - -## โš ๏ธ Breaking Changes -- ๐Ÿ› ๏ธ **Config**: [Optional: Changes to TOML config] -- ๐Ÿ”Œ **API/CLI**: [Optional: Breaking interface changes] -- ๐Ÿ—‘๏ธ **Deprecated Features**: [Optional: Removed features] - -## ๐Ÿ“‹ Configuration Updates -- ๐Ÿงพ **Config Diff**: [Link to diff showing configuration changes] - -## โœ… Testing & Validation -- **Test cases**: [Link to added e2e test cases] - -## ๐Ÿ“ฆ Full Changelog -[Auto-generated PR list and detailed changes] \ No newline at end of file From b55ecc9a60ce3cd6f57c752387148d5f9d09c0a1 Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Mon, 8 Sep 2025 13:47:29 +0000 Subject: [PATCH 17/27] Update config change footer token in cliff.toml --- cliff.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cliff.toml b/cliff.toml index ddb80361b..786b8b518 100644 --- a/cliff.toml +++ b/cliff.toml @@ -20,7 +20,7 @@ body = """ {%- set config_change_commits = [] -%} {%- for commit in commits -%} {%- for footer in commit.footers -%} - {%- if footer.token == 'CONFIG-CHANGE' -%} + {%- if footer.token == '## ๐Ÿ“‹ Config Updates' -%} {%- set_global config_change_commits = config_change_commits | concat(with=commit) -%} {%- endif -%} {%- endfor -%} @@ -50,7 +50,7 @@ body = """ ## ๐Ÿ“‹ Configuration Changes {%- for commit in config_change_commits %} {%- for line in commit.footers %} - {%- if line.token == 'CONFIG-CHANGE' %} + {%- if line.token == '## ๐Ÿ“‹ Config Updates' %} - {{ line.value | trim }} ***Original commit:*** {% if commit.type %}{{ commit.type }}{% endif -%}{% if commit.scope %}(_{{commit.scope}}_){% endif -%} {{ commit.message | trim }} {%- endif %} From 7d49d6d3e679d62e1771455afadd4f6a58d80887 Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Mon, 8 Sep 2025 13:48:18 +0000 Subject: [PATCH 18/27] Trigger release workflow only on tag pushes --- .github/workflows/release.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f1ec96d8c..e5312c80e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,8 +2,6 @@ name: Release on: push: - branches: - - feat/ci-revamp tags: - "v*.*.*" - "v*.*.*-*" From c830d942ba004e066f81fdb24031a2364058be8f Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Mon, 8 Sep 2025 13:54:55 +0000 Subject: [PATCH 19/27] Enable security scan job and restrict release trigger branch --- .github/workflows/release.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e5312c80e..627ebb8c8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,6 +2,8 @@ name: Release on: push: + branches: + - feat/ci-revamp tags: - "v*.*.*" - "v*.*.*-*" @@ -113,9 +115,9 @@ jobs: # needs: setup # uses: ./.github/workflows/test-e2e.yml - # security-scan: - # needs: setup - # uses: ./.github/workflows/test-security.yml + security-scan: + needs: setup + uses: ./.github/workflows/test-security.yml build: runs-on: amd-runner-2204 From 14d20287e7a2895bbd6b97ca325d41a0d02d0445 Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Mon, 8 Sep 2025 13:55:08 +0000 Subject: [PATCH 20/27] Require security scan to complete before build job --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 627ebb8c8..30c33e9e9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -121,7 +121,7 @@ jobs: build: runs-on: amd-runner-2204 - needs: [setup, unit-tests] + needs: [setup, unit-tests, security-scan] if: needs.setup.outputs.version-changed == 'true' && needs.unit-tests.result == 'success' && needs.integration-tests.result == 'success' && needs.security-scan.result == 'success' strategy: fail-fast: false From 2966304857bc68faa696bab908ca17b73ad462fc Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Mon, 8 Sep 2025 14:05:38 +0000 Subject: [PATCH 21/27] Update PR template and config parsing for config/breaking changes - Move breaking changes section to end of PR template - Standardize config and breaking change markers for parsing - Update cliff.toml to match new PR template tokens --- .github/PULL_REQUEST_TEMPLATE.md | 10 ++++------ cliff.toml | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index a6553852a..c0901ea6f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,13 +1,8 @@ ## ๐Ÿ”„ Changes Summary - [Brief description of what was added, fixed, or changed in this PR] -## โš ๏ธ Breaking Changes -- ๐Ÿ› ๏ธ **Config**: [Optional: Changes to TOML config] -- ๐Ÿ”Œ **API/CLI**: [Optional: Breaking interface changes] -- ๐Ÿ—‘๏ธ **Deprecated Features**: [Optional: Removed features] - ## ๐Ÿ“‹ Config Updates -- ๐Ÿงพ **Diff/Config snippet**: [Optional: Enumerate config changes/provide snippet of changes] +CONFIG-CHANGE: [Optional: Enumerate config changes/provide snippet of changes] ## โœ… Testing - ๐Ÿค– **Automatic**: [Optional: Enumerate E2E tests] @@ -21,3 +16,6 @@ ## ๐Ÿ“ Notes - [Optional: design decisions, tradeoffs, or TODOs] + +## โš ๏ธ Breaking Changes +BREAKING-CHANGE: [Optional: Enumerate breaking changes] diff --git a/cliff.toml b/cliff.toml index 786b8b518..ddb80361b 100644 --- a/cliff.toml +++ b/cliff.toml @@ -20,7 +20,7 @@ body = """ {%- set config_change_commits = [] -%} {%- for commit in commits -%} {%- for footer in commit.footers -%} - {%- if footer.token == '## ๐Ÿ“‹ Config Updates' -%} + {%- if footer.token == 'CONFIG-CHANGE' -%} {%- set_global config_change_commits = config_change_commits | concat(with=commit) -%} {%- endif -%} {%- endfor -%} @@ -50,7 +50,7 @@ body = """ ## ๐Ÿ“‹ Configuration Changes {%- for commit in config_change_commits %} {%- for line in commit.footers %} - {%- if line.token == '## ๐Ÿ“‹ Config Updates' %} + {%- if line.token == 'CONFIG-CHANGE' %} - {{ line.value | trim }} ***Original commit:*** {% if commit.type %}{{ commit.type }}{% endif -%}{% if commit.scope %}(_{{commit.scope}}_){% endif -%} {{ commit.message | trim }} {%- endif %} From 0d1a35727fabb81ae64724f56a1f3f5c6f3f200b Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Mon, 8 Sep 2025 14:09:59 +0000 Subject: [PATCH 22/27] Disable cancel-in-progress in test-security workflow --- .github/workflows/test-security.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-security.yml b/.github/workflows/test-security.yml index f9beaceec..c37fb8dde 100644 --- a/.github/workflows/test-security.yml +++ b/.github/workflows/test-security.yml @@ -6,7 +6,7 @@ on: concurrency: group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + cancel-in-progress: false jobs: govulncheck_job: From a3f2f61715f4855a000b6a0571c093b1f21a14d0 Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Mon, 8 Sep 2025 14:14:57 +0000 Subject: [PATCH 23/27] Update concurrency group in test-security workflow --- .github/workflows/test-security.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-security.yml b/.github/workflows/test-security.yml index c37fb8dde..7e59f06d2 100644 --- a/.github/workflows/test-security.yml +++ b/.github/workflows/test-security.yml @@ -5,7 +5,7 @@ on: workflow_call: {} concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: test-security-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: false jobs: From 599dc5a1e8c56fc0562f86cc3e9992be602c3eca Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Tue, 9 Sep 2025 08:44:19 +0000 Subject: [PATCH 24/27] Enable integration tests in release workflow --- .github/workflows/release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 30c33e9e9..614b8868d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -111,9 +111,9 @@ jobs: uses: ./.github/workflows/test-unit.yml secrets: inherit - # integration-tests: - # needs: setup - # uses: ./.github/workflows/test-e2e.yml + integration-tests: + needs: setup + uses: ./.github/workflows/test-e2e.yml security-scan: needs: setup From 510c07f0258b702563f1a14ca92f208d79754546 Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Tue, 9 Sep 2025 08:47:32 +0000 Subject: [PATCH 25/27] Remove integration-tests job from release workflow --- .github/workflows/release.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 614b8868d..ff2ad8815 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -111,10 +111,6 @@ jobs: uses: ./.github/workflows/test-unit.yml secrets: inherit - integration-tests: - needs: setup - uses: ./.github/workflows/test-e2e.yml - security-scan: needs: setup uses: ./.github/workflows/test-security.yml From cb620562f63911acc7d09347c2efb6b09e319ddc Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Tue, 9 Sep 2025 08:50:51 +0000 Subject: [PATCH 26/27] Update concurrency group name in test-e2e workflow --- .github/workflows/test-e2e.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index d4ff68f48..4e5d7ef9c 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -14,7 +14,7 @@ on: workflow_call: {} concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: test-e2e-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: From 4187b3ca1077977c544e1954fb5ef1ecfd4a710a Mon Sep 17 00:00:00 2001 From: Victor Castell <0x@vcastellm.xyz> Date: Tue, 9 Sep 2025 08:53:53 +0000 Subject: [PATCH 27/27] Add integration tests job to release workflow --- .github/workflows/release.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ff2ad8815..b4f4c1da7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -111,13 +111,17 @@ jobs: uses: ./.github/workflows/test-unit.yml secrets: inherit + integration-tests: + needs: setup + uses: ./.github/workflows/test-e2e.yml + security-scan: needs: setup uses: ./.github/workflows/test-security.yml build: runs-on: amd-runner-2204 - needs: [setup, unit-tests, security-scan] + needs: [setup, unit-tests, security-scan, integration-tests] if: needs.setup.outputs.version-changed == 'true' && needs.unit-tests.result == 'success' && needs.integration-tests.result == 'success' && needs.security-scan.result == 'success' strategy: fail-fast: false