|
| 1 | +# GitHub Workflows |
| 2 | + |
| 3 | +This directory contains the GitHub Actions workflows for the Grants Stack Indexer project. These workflows handle continuous integration, testing, and deployment processes. |
| 4 | + |
| 5 | +## Available Workflows |
| 6 | + |
| 7 | +| Workflow | Description | |
| 8 | +| ------------------------ | ----------------------------------------------- | |
| 9 | +| `main-workflow.yml` | Main CI pipeline triggered on PR to dev/main | |
| 10 | +| `build.yml` | Handles project building and type checking | |
| 11 | +| `build-image.yml` | Builds and validates Docker images | |
| 12 | +| `lint.yml` | Runs code linting and commit message validation | |
| 13 | +| `test.yml` | Executes unit tests with coverage | |
| 14 | +| `test-integration.yml` | Runs integration tests | |
| 15 | +| `create-ecr.yml` | Creates ECR repository in AWS | |
| 16 | +| `create-s3.yaml` | Creates S3 bucket for terraform state | |
| 17 | +| `deploy-to-aws.yaml` | First-time deployment to AWS | |
| 18 | +| `deploy-blue-green.yml` | Handles blue-green deployment (Step 1) | |
| 19 | +| `promote-blue-green.yml` | Promotes blue-green deployment (Step 2) | |
| 20 | +| `destroy-blue-green.yml` | Finalizes blue-green deployment (Step 3) | |
| 21 | +| `destroy-deployment.yml` | Destroys environment resources | |
| 22 | + |
| 23 | +## Main Workflow |
| 24 | + |
| 25 | +The main workflow (`main-workflow.yml`) is triggered on pull requests to `dev` and `main` branches. It orchestrates the following jobs in sequence: |
| 26 | + |
| 27 | +1. Build |
| 28 | +2. Build Image |
| 29 | +3. Lint (after Build) |
| 30 | +4. Tests (after Lint) |
| 31 | +5. Integration Tests (after Lint) |
| 32 | + |
| 33 | +## Deployment |
| 34 | + |
| 35 | +### Infrastructure Setup |
| 36 | + |
| 37 | +Before deploying the application, you need to set up the basic infrastructure: |
| 38 | + |
| 39 | +1. **Create S3 Bucket** (`create-s3.yaml`): |
| 40 | + |
| 41 | + - Creates bucket for Terraform state |
| 42 | + - Run once before the first deployment |
| 43 | + |
| 44 | +2. **Create ECR Repository** (`create-ecr.yml`): |
| 45 | + - Sets up Docker image registry |
| 46 | + - Run once before the first deployment |
| 47 | + |
| 48 | +Note: Once you deploy ECR registry, you will need to set `ECR_REGISTRY` in the repository settings. |
| 49 | + |
| 50 | +### Base Deployment |
| 51 | + |
| 52 | +Two workflows handle the base deployment operations: |
| 53 | + |
| 54 | +1. **First Deployment** (`deploy-to-aws.yaml`): |
| 55 | + |
| 56 | + - Sets up initial infrastructure |
| 57 | + - Deploys green environment |
| 58 | + |
| 59 | +2. **Environment Cleanup** (`destroy-deployment.yml`): |
| 60 | + - Removes all infrastructure |
| 61 | + - Use with caution |
| 62 | + |
| 63 | +### Blue-Green Deployment |
| 64 | + |
| 65 | +For updates, use the blue-green deployment process: |
| 66 | + |
| 67 | +1. **Deploy** (`deploy-blue-green.yml`): Create new environment |
| 68 | +2. **Promote** (`promote-blue-green.yml`): Switch traffic |
| 69 | +3. **Cleanup** (`destroy-blue-green.yml`): Remove old environment |
| 70 | + |
| 71 | +#### Blue-Green Deployment Details |
| 72 | + |
| 73 | +The blue-green deployment process consists of three steps: |
| 74 | + |
| 75 | +1. **Deploy New Environment** (`deploy-blue-green.yml`): |
| 76 | + |
| 77 | + - Creates a new environment (blue or green) alongside existing one |
| 78 | + - Deploys latest application version |
| 79 | + - New environment remains isolated from production traffic |
| 80 | + |
| 81 | +2. **Promote Environment** (`promote-blue-green.yml`): |
| 82 | + |
| 83 | + - Switches traffic from old to new environment |
| 84 | + - Validates new environment health |
| 85 | + - Updates DNS/load balancer routing |
| 86 | + |
| 87 | +3. **Cleanup Old Environment** (`destroy-blue-green.yml`): |
| 88 | + - Removes old environment after successful promotion |
| 89 | + - Releases unused resources |
| 90 | + - Completes deployment cycle |
| 91 | + |
| 92 | +Each step requires manual trigger with environment selection (blue/green) to ensure controlled deployment process. |
| 93 | + |
| 94 | +## Required Configuration |
| 95 | + |
| 96 | +###Environment Variables and Secrets |
| 97 | +To properly configure your GitHub repository, set up the following environment variables and secrets: |
| 98 | + |
| 99 | +1. Add Repository Secrets |
| 100 | + Navigate to GitHub Repository Settings → Secrets and add: |
| 101 | + |
| 102 | +- `AWS_ACCESS_KEY_ID` |
| 103 | +- `AWS_SECRET_ACCESS_KEY` |
| 104 | +- `ECR_REGISTRY` |
| 105 | + |
| 106 | +2. Add Repository Environment Variables |
| 107 | + Under GitHub Repository Settings → Environment Variables, add: |
| 108 | + |
| 109 | +- `APP_NAME` |
| 110 | +- `AWS_REGION` |
| 111 | + |
| 112 | +3. Create GitHub Environments |
| 113 | + Set up two separate GitHub Environments: |
| 114 | + |
| 115 | +- `production` |
| 116 | +- `staging` |
| 117 | + |
| 118 | +4. Add Secrets to GitHub Environments |
| 119 | + Within each environment (production and staging), add: |
| 120 | + |
| 121 | +- `COINGECKO_API_KEY` |
| 122 | +- `DATALAYER_HASURA_ADMIN_SECRET` |
| 123 | +- `DATALAYER_PG_PASSWORD` |
| 124 | +- `DATALAYER_PG_USER` |
| 125 | + |
| 126 | +5. Add Environment Variables to GitHub Environments |
| 127 | + Under Repository Environment Variables, add: |
| 128 | + |
| 129 | +- `TERRAFORM_VARS` (Primarily used for managing image tag updates) |
| 130 | + Example `TERRAFORM_VARS` configuration: |
| 131 | + |
| 132 | +```json |
| 133 | +{ |
| 134 | + "GREEN_PROCESSING_IMAGE_TAG": "d8cece196697abbdafa5a7027e0b12f0ffe8bd77", |
| 135 | + "BLUE_PROCESSING_IMAGE_TAG": "d8cece196697abbdafa5a7027e0b12f0ffe8bd77", |
| 136 | + "GREEN_API_REPOSITORY_URL": "registry.hub.docker.com/hasura/graphql-engine", |
| 137 | + "GREEN_API_IMAGE_TAG": "v2.23.0", |
| 138 | + "GREEN_NODE_ENV": "production", |
| 139 | + "GREEN_RETRY_MAX_ATTEMPTS": 10, |
| 140 | + "GREEN_RETRY_BASE_DELAY_MS": 200, |
| 141 | + "GREEN_RETRY_MAX_DELAY_MS": 1000, |
| 142 | + "GREEN_RETRY_FACTOR": 1.5, |
| 143 | + "GREEN_CHAINS": [ |
| 144 | + { |
| 145 | + "id": 10, |
| 146 | + "name": "optimism", |
| 147 | + "rpcUrls": [ |
| 148 | + "https://optimism.llamarpc.com", |
| 149 | + "https://rpc.ankr.com/optimism", |
| 150 | + "https://optimism.gateway.tenderly.co", |
| 151 | + "https://optimism.blockpi.network/v1/rpc/public", |
| 152 | + "https://mainnet.optimism.io", |
| 153 | + "https://opt-mainnet.g.alchemy.com/v2/demo" |
| 154 | + ], |
| 155 | + "fetchLimit": 1000, |
| 156 | + "fetchDelayMs": 2000 |
| 157 | + }, |
| 158 | + { |
| 159 | + "id": 1, |
| 160 | + "name": "mainnet", |
| 161 | + "rpcUrls": ["https://eth.llamarpc.com", "https://rpc.flashbots.net/fast"], |
| 162 | + "fetchLimit": 1000, |
| 163 | + "fetchDelayMs": 2000 |
| 164 | + } |
| 165 | + ], |
| 166 | + "GREEN_INDEXER_GRAPHQL_URL": "https://indexer.dev.hyperindex.xyz/e6a0458/v1/graphql", |
| 167 | + "GREEN_METADATA_SOURCE": "public-gateway", |
| 168 | + "GREEN_PUBLIC_GATEWAY_URLS": [ |
| 169 | + "https://ipfs.io", |
| 170 | + "https://dweb.link", |
| 171 | + "https://cloudflare-ipfs.com", |
| 172 | + "https://gateway.pinata.cloud", |
| 173 | + "https://ipfs.infura.io", |
| 174 | + "https://ipfs.fleek.co", |
| 175 | + "https://ipfs.eth.aragon.network", |
| 176 | + "https://ipfs.jes.xxx", |
| 177 | + "https://ipfs.lol", |
| 178 | + "https://ipfs.mle.party" |
| 179 | + ], |
| 180 | + "GREEN_PRICING_SOURCE": "coingecko", |
| 181 | + "GREEN_COINGECKO_API_TYPE": "pro", |
| 182 | + "GREEN_LOG_LEVEL": "info", |
| 183 | + "GREEN_DATALAYER_PG_DB_NAME": "GitcoinDatalayerGreen", |
| 184 | + "BLUE_API_REPOSITORY_URL": "registry.hub.docker.com/hasura/graphql-engine", |
| 185 | + "BLUE_API_IMAGE_TAG": "v2.23.0", |
| 186 | + "BLUE_NODE_ENV": "production", |
| 187 | + "BLUE_RETRY_MAX_ATTEMPTS": 10, |
| 188 | + "BLUE_RETRY_BASE_DELAY_MS": 200, |
| 189 | + "BLUE_RETRY_MAX_DELAY_MS": 1000, |
| 190 | + "BLUE_RETRY_FACTOR": 1.5, |
| 191 | + "BLUE_CHAINS": [ |
| 192 | + { |
| 193 | + "id": 10, |
| 194 | + "name": "optimism", |
| 195 | + "rpcUrls": [ |
| 196 | + "https://optimism.llamarpc.com", |
| 197 | + "https://rpc.ankr.com/optimism", |
| 198 | + "https://optimism.gateway.tenderly.co", |
| 199 | + "https://optimism.blockpi.network/v1/rpc/public", |
| 200 | + "https://mainnet.optimism.io", |
| 201 | + "https://opt-mainnet.g.alchemy.com/v2/demo" |
| 202 | + ], |
| 203 | + "fetchLimit": 1000, |
| 204 | + "fetchDelayMs": 2000 |
| 205 | + }, |
| 206 | + { |
| 207 | + "id": 1, |
| 208 | + "name": "mainnet", |
| 209 | + "rpcUrls": ["https://eth.llamarpc.com", "https://rpc.flashbots.net/fast"], |
| 210 | + "fetchLimit": 1000, |
| 211 | + "fetchDelayMs": 2000 |
| 212 | + } |
| 213 | + ], |
| 214 | + "BLUE_INDEXER_GRAPHQL_URL": "https://indexer.dev.hyperindex.xyz/e6a0458/v1/graphql", |
| 215 | + "BLUE_METADATA_SOURCE": "public-gateway", |
| 216 | + "BLUE_PUBLIC_GATEWAY_URLS": [ |
| 217 | + "https://ipfs.io", |
| 218 | + "https://dweb.link", |
| 219 | + "https://cloudflare-ipfs.com", |
| 220 | + "https://gateway.pinata.cloud", |
| 221 | + "https://ipfs.infura.io", |
| 222 | + "https://ipfs.fleek.co", |
| 223 | + "https://ipfs.eth.aragon.network", |
| 224 | + "https://ipfs.jes.xxx", |
| 225 | + "https://ipfs.lol", |
| 226 | + "https://ipfs.mle.party" |
| 227 | + ], |
| 228 | + "BLUE_PRICING_SOURCE": "coingecko", |
| 229 | + "BLUE_COINGECKO_API_TYPE": "pro", |
| 230 | + "BLUE_LOG_LEVEL": "info", |
| 231 | + "BLUE_DATALAYER_PG_DB_NAME": "GitcoinDatalayerBlue" |
| 232 | +} |
| 233 | +``` |
| 234 | + |
| 235 | +## Docker Image Management |
| 236 | + |
| 237 | +### Building Images |
| 238 | + |
| 239 | +The `build-image.yml` workflow: |
| 240 | + |
| 241 | +- Uses Docker Buildx |
| 242 | +- Implements layer caching |
| 243 | +- Targets the processing stage |
| 244 | + |
| 245 | +### ECR Push |
| 246 | + |
| 247 | +The `push-to-ecr.yaml` workflow automatically pushes images to Amazon ECR when changes are pushed to the `dev` branch. |
| 248 | + |
| 249 | +Required secrets for ECR: |
| 250 | + |
| 251 | +- `ECR_REGISTRY` |
| 252 | +- `AWS_ACCESS_KEY_ID` |
| 253 | +- `AWS_SECRET_ACCESS_KEY` |
0 commit comments