From 8be1987b0aa67d15b743038d8946b3f8633c2082 Mon Sep 17 00:00:00 2001 From: abs2023 Date: Tue, 27 Jan 2026 14:48:07 -0500 Subject: [PATCH 1/2] refactor: DRY version tagging with gen-tag composite action - Add reusable .github/actions/gen-tag composite action - Standardize component-based versioning: -v[-env] - Tags now created for all environments (dev, stg, main) - Baseline version: proxy-router-v3.1.0 --- .github/actions/gen-tag/action.yml | 147 ++++++++++++++++++ .../workflows/build-deploy-proxy-router.yml | 85 +++------- 2 files changed, 165 insertions(+), 67 deletions(-) create mode 100644 .github/actions/gen-tag/action.yml diff --git a/.github/actions/gen-tag/action.yml b/.github/actions/gen-tag/action.yml new file mode 100644 index 0000000..c9fd7d2 --- /dev/null +++ b/.github/actions/gen-tag/action.yml @@ -0,0 +1,147 @@ +name: 'Generate Version Tag' +description: 'Generates component-based version tags for monorepo deployments' + +inputs: + component: + description: 'Component name (folder name, e.g., indexer, ui, oracle-update)' + required: true + major_version: + description: 'Target major version (triggers major bump if greater than current)' + required: false + default: '3' + environment_override: + description: 'Override environment (for workflow_dispatch). Leave empty for branch-based detection.' + required: false + default: '' + +outputs: + tag_name: + description: 'Full tag name (e.g., indexer-v2.0.5-dev)' + value: ${{ steps.gen_tag.outputs.tag_name }} + vtag: + description: 'Version tag (same as tag_name)' + value: ${{ steps.gen_tag.outputs.vtag }} + version: + description: 'Version string with v prefix (e.g., v2.0.5-dev)' + value: ${{ steps.gen_tag.outputs.version }} + vfull: + description: 'Semantic version without prefix (e.g., 2.0.5)' + value: ${{ steps.gen_tag.outputs.vfull }} + environment: + description: 'Deployment environment (dev, stg, main)' + value: ${{ steps.determine_env.outputs.environment }} + should_create_release: + description: 'Whether to create a GitHub release (true for main)' + value: ${{ steps.determine_env.outputs.should_create_release }} + is_cicd_branch: + description: 'Whether this is a CI/CD test branch' + value: ${{ steps.determine_env.outputs.is_cicd_branch }} + +runs: + using: 'composite' + steps: + - name: Determine environment + id: determine_env + shell: bash + run: | + ENV_OVERRIDE="${{ inputs.environment_override }}" + IS_CICD="false" + + if [ -n "$ENV_OVERRIDE" ]; then + # Use override from workflow_dispatch + ENV="$ENV_OVERRIDE" + CREATE_RELEASE="false" + [ "$ENV" == "main" ] && CREATE_RELEASE="true" + else + # Detect from branch name + BRANCH="${{ github.ref_name }}" + if [ "$BRANCH" == "main" ]; then + ENV="main" + CREATE_RELEASE="true" + elif [ "$BRANCH" == "stg" ]; then + ENV="stg" + CREATE_RELEASE="false" + elif [[ "$BRANCH" == cicd/* ]]; then + ENV="dev" + CREATE_RELEASE="false" + IS_CICD="true" + echo "🔧 CI/CD test branch detected - will skip build/deploy" + else + ENV="dev" + CREATE_RELEASE="false" + fi + fi + echo "environment=${ENV}" >> $GITHUB_OUTPUT + echo "should_create_release=${CREATE_RELEASE}" >> $GITHUB_OUTPUT + echo "is_cicd_branch=${IS_CICD}" >> $GITHUB_OUTPUT + + - name: Generate version tag + id: gen_tag + shell: bash + run: | + # Component-based versioning for monorepo + # Pattern: -v..[-env] + COMPONENT="${{ inputs.component }}" + VMAJ_NEW=${{ inputs.major_version }} + VMIN_NEW=0 + VPAT_NEW=0 + + set +o pipefail + + # Find the last production tag for this component (without -dev/-stg suffix) + # Use git tag -l with sort to find latest, not git describe (which requires reachability) + VLAST=$(git tag -l "${COMPONENT}-v[0-9]*" | grep -E "^${COMPONENT}-v[0-9]+\.[0-9]+\.[0-9]+$" | sort -V | tail -n 1 | sed "s/${COMPONENT}-v//" || echo "") + + if [ -n "$VLAST" ]; then + # Parse existing version + eval $(echo "$VLAST" | awk -F '.' '{print "VMAJ="$1" VMIN="$2" VPAT="$3}') + else + # No existing tags - start fresh + VMAJ=$VMAJ_NEW + VMIN=0 + VPAT=0 + fi + + ENV="${{ steps.determine_env.outputs.environment }}" + + if [ "$ENV" = "main" ]; then + # Production release - increment version + if [ "$VMAJ_NEW" -gt "$VMAJ" ]; then + # Major version bump requested + VMAJ=$VMAJ_NEW + VMIN=$VMIN_NEW + VPAT=$VPAT_NEW + else + # Increment minor version, reset patch + VMIN=$((VMIN+1)) + VPAT=0 + fi + VFULL=${VMAJ}.${VMIN}.${VPAT} + VTAG=${COMPONENT}-v${VFULL} + VERSION="v${VFULL}" + else + # Non-production - use commit count as patch for uniqueness + MB=$(git merge-base refs/remotes/origin/main HEAD 2>/dev/null || git rev-parse HEAD) + VPAT=$(git rev-list --count --no-merges ${MB}..HEAD 2>/dev/null || echo "0") + VFULL=${VMAJ}.${VMIN}.${VPAT} + RNAME=${GITHUB_REF_NAME##*/} + [ "$GITHUB_EVENT_NAME" = "pull_request" ] && RNAME=pr${GITHUB_REF_NAME%/merge} + VTAG=${COMPONENT}-v${VFULL}-${RNAME} + VERSION="v${VFULL}-${RNAME}" + fi + + # Output variables + echo "tag_name=${VTAG}" >> $GITHUB_OUTPUT + echo "vtag=${VTAG}" >> $GITHUB_OUTPUT + echo "version=${VERSION}" >> $GITHUB_OUTPUT + echo "vfull=${VFULL}" >> $GITHUB_OUTPUT + + # Summary + echo "📦 Component: ${COMPONENT}" >> $GITHUB_STEP_SUMMARY + echo "🌍 Environment: ${ENV}" >> $GITHUB_STEP_SUMMARY + echo "✅ Proposed Tag: ${VTAG} (will be created after successful deployment)" >> $GITHUB_STEP_SUMMARY + if [ -n "$VLAST" ]; then + echo "📋 Last Production Tag: ${COMPONENT}-v${VLAST}" >> $GITHUB_STEP_SUMMARY + else + echo "📋 Last Production Tag: (none - first deployment)" >> $GITHUB_STEP_SUMMARY + fi diff --git a/.github/workflows/build-deploy-proxy-router.yml b/.github/workflows/build-deploy-proxy-router.yml index aef3082..e92a46a 100644 --- a/.github/workflows/build-deploy-proxy-router.yml +++ b/.github/workflows/build-deploy-proxy-router.yml @@ -38,12 +38,13 @@ jobs: runs-on: ubuntu-latest name: Generate Tag Name outputs: - tag_name: ${{ steps.gen_tag_name.outputs.tag_name }} - vtag: ${{ steps.gen_tag_name.outputs.vtag }} - vfull: ${{ steps.gen_tag_name.outputs.vfull }} - image_name: ${{ steps.gen_tag_name.outputs.image_name }} - environment: ${{ steps.gen_tag_name.outputs.environment }} - is_cicd_branch: ${{ steps.gen_tag_name.outputs.is_cicd_branch }} + tag_name: ${{ steps.gen_tag.outputs.tag_name }} + vtag: ${{ steps.gen_tag.outputs.vtag }} + vfull: ${{ steps.gen_tag.outputs.vfull }} + version: ${{ steps.gen_tag.outputs.version }} + image_name: ${{ steps.config.outputs.image_name }} + environment: ${{ steps.gen_tag.outputs.environment }} + is_cicd_branch: ${{ steps.gen_tag.outputs.is_cicd_branch }} steps: - name: Clone repository uses: actions/checkout@v4 @@ -51,70 +52,20 @@ jobs: fetch-depth: 0 fetch-tags: true - - name: Determine tag name - id: gen_tag_name - shell: bash + - name: Generate version tag + id: gen_tag + uses: ./.github/actions/gen-tag + with: + component: proxy-router + major_version: '3' + + - name: Config + id: config run: | IMAGE_NAME="ghcr.io/lumerin-protocol/proxy-router" - VMAJ_NEW=1 - VMIN_NEW=2 - VPAT_NEW=4 - IS_CICD="false" - set +o pipefail - VLAST=$(git describe --tags --abbrev=0 --match='v[1-9]*' refs/remotes/origin/main 2>/dev/null | cut -c2-) - - if [ -n "$VLAST" ]; then - eval $(echo "$VLAST" | awk -F '.' '{print "VMAJ="$1" VMIN="$2" VPAT="$3}') - else - VMAJ=0 - VMIN=0 - VPAT=0 - fi - - # Determine environment - if [ "$GITHUB_REF_NAME" = "main" ]; then - ENV="main" - elif [ "$GITHUB_REF_NAME" = "stg" ]; then - ENV="stg" - elif [[ "$GITHUB_REF_NAME" == cicd/* ]]; then - ENV="dev" - IS_CICD="true" - echo "🔧 CI/CD test branch detected - will run build test only" - else - ENV="dev" - fi - - if [ "$GITHUB_REF_NAME" = "main" ]; then - if [ "$VMAJ_NEW" -gt "$VMAJ" ]; then - VMAJ=$VMAJ_NEW - VMIN=$VMIN_NEW - VPAT=$VPAT_NEW - else - VMIN=$((VMIN+1)) - VPAT=0 - fi - VFULL=${VMAJ}.${VMIN}.${VPAT} - VTAG=v$VFULL - else - MB=$(git merge-base refs/remotes/origin/main HEAD) - VPAT=$(git rev-list --count --no-merges ${MB}..HEAD) - VFULL=${VMAJ}.${VMIN}.${VPAT} - RNAME=${GITHUB_REF_NAME##*/} - [ "$GITHUB_EVENT_NAME" = "pull_request" ] && RNAME=pr${GITHUB_REF_NAME%/merge} - VTAG=v${VFULL}-${RNAME} - fi - - # Output variables for use in subsequent jobs environment - echo "tag_name=${VTAG}" >> $GITHUB_OUTPUT - echo "vtag=${VTAG}" >> $GITHUB_OUTPUT - echo "vfull=${VFULL}" >> $GITHUB_OUTPUT echo "image_name=${IMAGE_NAME}" >> $GITHUB_OUTPUT - echo "environment=${ENV}" >> $GITHUB_OUTPUT - echo "is_cicd_branch=${IS_CICD}" >> $GITHUB_OUTPUT - echo "✅ New Build Tag: $VTAG" >> $GITHUB_STEP_SUMMARY - echo "✅ Docker Image: ${IMAGE_NAME}:${VTAG}" >> $GITHUB_STEP_SUMMARY - echo "🌍 Environment: ${ENV}" >> $GITHUB_STEP_SUMMARY - if [ "$IS_CICD" == "true" ]; then + echo "✅ Docker Image: ${IMAGE_NAME}:${{ steps.gen_tag.outputs.tag_name }}" >> $GITHUB_STEP_SUMMARY + if [ "${{ steps.gen_tag.outputs.is_cicd_branch }}" == "true" ]; then echo "🔧 CI/CD Test Mode: Build test only" >> $GITHUB_STEP_SUMMARY fi From 76cfeb181e4f5f8f6b71fa7969bdbd49e283be6f Mon Sep 17 00:00:00 2001 From: abs2023 Date: Wed, 28 Jan 2026 10:02:09 -0500 Subject: [PATCH 2/2] feat: Add Graph API key and Futures subgraph ID variables - Introduced new variables for Graph API key and Futures subgraph ID in 00_variables.tf. - Updated secrets manager configurations to include Futures subgraph URL in 01_secrets_manager.tf. - Modified ECS task definitions to reference the new Futures subgraph URL in 02_proxy_n_router_svc.tf and 02_proxy_n_validator_svc.tf. - Adjusted GitHub Actions workflow to construct Futures subgraph URL dynamically in build-deploy-proxy-router.yml. --- .bedrock/.terragrunt/00_variables.tf | 14 ++++++++++++++ .bedrock/.terragrunt/01_secrets_manager.tf | 10 ++++++---- .bedrock/.terragrunt/02_proxy_n_router_svc.tf | 4 ++-- .bedrock/.terragrunt/02_proxy_n_validator_svc.tf | 4 ++-- .github/workflows/build-deploy-proxy-router.yml | 4 +++- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/.bedrock/.terragrunt/00_variables.tf b/.bedrock/.terragrunt/00_variables.tf index 485badd..c45d29a 100644 --- a/.bedrock/.terragrunt/00_variables.tf +++ b/.bedrock/.terragrunt/00_variables.tf @@ -330,3 +330,17 @@ variable "validator_eth_node_address" { sensitive = true default = "" } + +variable "graph_api_key" { + description = "The Graph API Key for accessing published subgraphs" + type = string + sensitive = true + default = "" +} + +variable "futures_subgraph_id" { + description = "The Graph Subgraph ID for Futures (from published subgraph)" + type = string + sensitive = true + default = "" +} diff --git a/.bedrock/.terragrunt/01_secrets_manager.tf b/.bedrock/.terragrunt/01_secrets_manager.tf index f0da9b2..ed15c4e 100644 --- a/.bedrock/.terragrunt/01_secrets_manager.tf +++ b/.bedrock/.terragrunt/01_secrets_manager.tf @@ -27,8 +27,9 @@ resource "aws_secretsmanager_secret_version" "proxy_router" { count = var.proxy_router["create"] ? 1 : 0 secret_id = aws_secretsmanager_secret.proxy_router[0].id secret_string = jsonencode({ - wallet_private_key = var.proxy_wallet_private_key - eth_node_address = var.proxy_eth_node_address + wallet_private_key = var.proxy_wallet_private_key + eth_node_address = var.proxy_eth_node_address + futures_subgraph_url = "https://gateway.thegraph.com/api/${var.graph_api_key}/subgraphs/id/${var.futures_subgraph_id}" }) } @@ -55,8 +56,9 @@ resource "aws_secretsmanager_secret_version" "proxy_validator" { count = var.proxy_validator["create"] ? 1 : 0 secret_id = aws_secretsmanager_secret.proxy_validator[0].id secret_string = jsonencode({ - wallet_private_key = var.validator_wallet_private_key - eth_node_address = var.validator_eth_node_address + wallet_private_key = var.validator_wallet_private_key + eth_node_address = var.validator_eth_node_address + futures_subgraph_url = "https://gateway.thegraph.com/api/${var.graph_api_key}/subgraphs/id/${var.futures_subgraph_id}" }) } diff --git a/.bedrock/.terragrunt/02_proxy_n_router_svc.tf b/.bedrock/.terragrunt/02_proxy_n_router_svc.tf index 4b1c0cc..b5f3052 100644 --- a/.bedrock/.terragrunt/02_proxy_n_router_svc.tf +++ b/.bedrock/.terragrunt/02_proxy_n_router_svc.tf @@ -87,7 +87,6 @@ resource "aws_ecs_task_definition" "proxy_router_use1_1" { launch_type = "FARGATE" essential = true environment = [ - { "name" : "FUTURES_SUBGRAPH_URL", "value" : var.account_lifecycle == "prd" ? "https://graph.lmn.lumerin.io/subgraphs/name/futures" : "https://graph.${var.account_lifecycle}.lumerin.io/subgraphs/name/futures" }, { "name" : "MULTICALL_ADDRESS", "value" : "0xcA11bde05977b3631167028862bE2a173976CA11" }, { "name" : "FUTURES_ADDRESS", "value" : var.futures_address }, # { "name" : "FUTURES_VALIDATOR_URL_OVERRIDE", "value" : var.futures_validator_url_override }, @@ -131,7 +130,8 @@ resource "aws_ecs_task_definition" "proxy_router_use1_1" { ] secrets = [ { "name" : "WALLET_PRIVATE_KEY", "valueFrom" : "${aws_secretsmanager_secret.proxy_router[0].arn}:wallet_private_key::" }, - { "name" : "ETH_NODE_ADDRESS", "valueFrom" : "${aws_secretsmanager_secret.proxy_router[0].arn}:eth_node_address::" } + { "name" : "ETH_NODE_ADDRESS", "valueFrom" : "${aws_secretsmanager_secret.proxy_router[0].arn}:eth_node_address::" }, + { "name" : "FUTURES_SUBGRAPH_URL", "valueFrom" : "${aws_secretsmanager_secret.proxy_router[0].arn}:futures_subgraph_url::" } ] portMappings = [ { diff --git a/.bedrock/.terragrunt/02_proxy_n_validator_svc.tf b/.bedrock/.terragrunt/02_proxy_n_validator_svc.tf index 5e1b392..d2df4aa 100644 --- a/.bedrock/.terragrunt/02_proxy_n_validator_svc.tf +++ b/.bedrock/.terragrunt/02_proxy_n_validator_svc.tf @@ -86,7 +86,6 @@ resource "aws_ecs_task_definition" "proxy_validator_use1_1" { launch_type = "FARGATE" essential = true environment = [ - { "name" : "FUTURES_SUBGRAPH_URL", "value" : var.account_lifecycle == "prd" ? "https://graph.lmn.lumerin.io/subgraphs/name/futures" : "https://graph.${var.account_lifecycle}.lumerin.io/subgraphs/name/futures" }, { "name" : "MULTICALL_ADDRESS", "value" : "0xcA11bde05977b3631167028862bE2a173976CA11" }, { "name" : "FUTURES_ADDRESS", "value" : var.futures_address }, # { "name" : "FUTURES_VALIDATOR_URL_OVERRIDE", "value" : var.futures_validator_url_override }, @@ -131,7 +130,8 @@ resource "aws_ecs_task_definition" "proxy_validator_use1_1" { ] secrets = [ { "name" : "WALLET_PRIVATE_KEY", "valueFrom" : "${aws_secretsmanager_secret.proxy_validator[0].arn}:wallet_private_key::" }, - { "name" : "ETH_NODE_ADDRESS", "valueFrom" : "${aws_secretsmanager_secret.proxy_validator[0].arn}:eth_node_address::" } + { "name" : "ETH_NODE_ADDRESS", "valueFrom" : "${aws_secretsmanager_secret.proxy_validator[0].arn}:eth_node_address::" }, + { "name" : "FUTURES_SUBGRAPH_URL", "valueFrom" : "${aws_secretsmanager_secret.proxy_validator[0].arn}:futures_subgraph_url::" } ] portMappings = [ { diff --git a/.github/workflows/build-deploy-proxy-router.yml b/.github/workflows/build-deploy-proxy-router.yml index e92a46a..e4e2537 100644 --- a/.github/workflows/build-deploy-proxy-router.yml +++ b/.github/workflows/build-deploy-proxy-router.yml @@ -101,8 +101,10 @@ jobs: run: | BUILDTAG=${{ needs.Generate-Tag.outputs.tag_name }} BUILDIMAGE=${{ needs.Generate-Tag.outputs.image_name }} + # Construct Graph URL from org secrets/vars (using DEV for CI testing) + FUTURES_SUBGRAPH_URL="https://gateway.thegraph.com/api/${{ secrets.DEV_GRAPH_APIKEY }}/subgraphs/id/${{ vars.DEV_FUTURES_SUBGRAPH_ID }}" docker run -d --name proxy-router-test \ - -e FUTURES_SUBGRAPH_URL=${{ vars.FUTURES_SUBGRAPH_URL }} \ + -e FUTURES_SUBGRAPH_URL="${FUTURES_SUBGRAPH_URL}" \ -e MULTICALL_ADDRESS=${{ vars.MULTICALL_ADDRESS }} \ -e FUTURES_ADDRESS=${{ vars.FUTURES_ADDRESS }} \ -e FUTURES_VALIDATOR_URL_OVERRIDE=${{ vars.FUTURES_VALIDATOR_URL_OVERRIDE }} \