Skip to content

Commit c7dda29

Browse files
committed
feature: terraform dev valide
1 parent 09454fc commit c7dda29

78 files changed

Lines changed: 9724 additions & 4284 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.releaserc.json renamed to .github/.releaserc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@
116116
{
117117
"assets": [
118118
"CHANGELOG.md",
119-
"package.json"
119+
".github/package.json"
120120
],
121121
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
122122
}

.github/GITHUB_ACTIONS_CICD.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# GitHub Actions CI/CD Guide
2+
3+
Reference for CI validation and deployment workflows in this repository.
4+
5+
## Workflows
6+
7+
- `ci.yml` — lint, tests, security/dependency checks, Terraform plan validation
8+
- `staging.yml` — staging build/apply/deploy/smoke-test
9+
- `release.yml` — semantic release and production deploy flow
10+
- `_smoke-test.yml` — reusable post-deploy health check
11+
12+
## `ci.yml`
13+
14+
Triggers:
15+
16+
- `pull_request` to `main` and `develop`
17+
- `push` to `main` and `develop`
18+
- `workflow_dispatch`
19+
20+
Responsibilities:
21+
22+
- Conventional commit check (PR)
23+
- Backend lint + unit/integration tests
24+
- Frontend lint + type-check + build
25+
- Trivy + GitGuardian scan
26+
- Snyk dependency audit
27+
- Terraform fmt/validate/plan (no apply)
28+
- Final `quality-gate` status
29+
30+
## `staging.yml`
31+
32+
Triggers:
33+
34+
- successful `CI` workflow run on `develop`
35+
- manual dispatch
36+
37+
Responsibilities:
38+
39+
- Build/push backend and frontend images to ECR
40+
- Apply staging Terraform
41+
- Force ECS rolling deploy for both services
42+
- Run reusable smoke test against `vars.APP_URL`
43+
44+
Config model:
45+
46+
- Non-secret values loaded from `config/.env.staging`
47+
- Secrets from GitHub Environment `staging`
48+
49+
## `release.yml`
50+
51+
Two flows:
52+
53+
1. Semantic release flow
54+
- Trigger: successful `CI` workflow run on `main` (or manual dispatch)
55+
- Runs semantic-release (creates version tag/release)
56+
2. Production deploy flow
57+
- Trigger: tag push `v*`
58+
- Builds/pushes images to ECR
59+
- Runs Terraform apply for production
60+
- Forces ECS deploy
61+
- Runs smoke test against `vars.APP_URL`
62+
63+
Config model:
64+
65+
- Uses GitHub Environment `production` secrets
66+
67+
## Required GitHub configuration
68+
69+
### Repository secrets
70+
71+
- `DATABASE_USER`
72+
- `DATABASE_PASSWORD`
73+
- `DATABASE_NAME`
74+
- `DATABASE_PORT`
75+
- `AWS_ROLE_TO_ASSUME`
76+
- `GITGUARDIAN_API_KEY`
77+
- `SNYK_TOKEN`
78+
79+
### Environment `staging` secrets
80+
81+
- `AWS_ROLE_TO_ASSUME`
82+
- `TERRAFORM_STATE_BUCKET`
83+
- `TERRAFORM_LOCK_TABLE` (compatibility input)
84+
- `JWT_SECRET_KEY`
85+
86+
### Environment `staging` vars
87+
88+
- `APP_URL`
89+
90+
### Environment `production` secrets
91+
92+
- `AWS_ROLE_TO_ASSUME`
93+
- `AWS_REGION`
94+
- `TF_VERSION`
95+
- `TERRAFORM_STATE_BUCKET`
96+
- `TERRAFORM_LOCK_TABLE` (compatibility input)
97+
- `JWT_SECRET_KEY`
98+
99+
### Environment `production` vars
100+
101+
- `APP_URL`
102+
103+
## Terraform backend lock note
104+
105+
Infrastructure init now uses `use_lockfile=true` for backend locking.
106+
107+
`TERRAFORM_LOCK_TABLE` remains exposed in current workflow inputs for backward compatibility.
108+
109+
## Related files
110+
111+
- `.github/workflows/ci.yml`
112+
- `.github/workflows/staging.yml`
113+
- `.github/workflows/release.yml`
114+
- `.github/workflows/_smoke-test.yml`

.github/actions/aws-auth/action.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
###############################################################################
2+
# composite action: aws-auth
3+
#
4+
# Authenticates the GitHub Actions runner with AWS by assuming an IAM role
5+
# via OIDC (no long-lived credentials stored in secrets).
6+
#
7+
# Callers: ci.yml (terraform-plan), staging.yml (terraform-staging,
8+
# deploy-staging), release.yml (terraform-production,
9+
# deploy-production)
10+
# Inputs: role-arn, aws-region
11+
###############################################################################
112
name: "AWS Authentication"
213
description: "Authenticate with AWS using OIDC"
314

.github/actions/docker-build/action.yml

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
###############################################################################
2+
# composite action: docker-build
3+
#
4+
# Builds a Docker image, optionally pushes it to a registry, and runs a
5+
# Trivy vulnerability scan on the resulting image.
6+
#
7+
# Callers: staging.yml (build job), release.yml (build-production job)
8+
# Inputs: context, dockerfile, image-name, registry, tags, build-args,
9+
# scan, scan-severity, scan-exit-code, cache-scope,
10+
# registry-username, registry-password
11+
###############################################################################
112
name: "Docker Build"
213
description: "Build and push Docker image to registry"
314

@@ -17,10 +28,12 @@ inputs:
1728
default: "ghcr.io"
1829
registry-username:
1930
description: "Registry username"
20-
required: true
31+
required: false
32+
default: ""
2133
registry-password:
2234
description: "Registry password/token"
23-
required: true
35+
required: false
36+
default: ""
2437
push:
2538
description: "Push to registry after build"
2639
required: false
@@ -29,6 +42,30 @@ inputs:
2942
description: "Run Trivy vulnerability scan"
3043
required: false
3144
default: "true"
45+
scan-severity:
46+
description: "Trivy severities to include"
47+
required: false
48+
default: "CRITICAL,HIGH"
49+
scan-exit-code:
50+
description: "Trivy exit code on findings"
51+
required: false
52+
default: "0"
53+
tags:
54+
description: "docker/metadata-action tag rules"
55+
required: false
56+
default: ""
57+
build-args:
58+
description: "Additional Docker build args"
59+
required: false
60+
default: ""
61+
cache-scope:
62+
description: "GHA cache scope"
63+
required: false
64+
default: ""
65+
platforms:
66+
description: "Target platforms for image build"
67+
required: false
68+
default: "linux/amd64"
3269
cache:
3370
description: "Use GitHub Actions cache"
3471
required: false
@@ -56,6 +93,7 @@ runs:
5693
uses: docker/setup-buildx-action@v2
5794

5895
- name: Login to registry
96+
if: inputs.registry-username != '' && inputs.registry-password != ''
5997
uses: docker/login-action@v2
6098
with:
6199
registry: ${{ inputs.registry }}
@@ -78,27 +116,25 @@ runs:
78116
uses: docker/metadata-action@v4
79117
with:
80118
images: ${{ inputs.registry }}/${{ inputs.image-name }}
81-
tags: |
82-
type=ref,event=branch
83-
type=sha,prefix={{branch}}-
84-
type=semver,pattern={{version}}
85-
type=raw,value=latest,enable={{is_default_branch}}
119+
tags: ${{ inputs.tags != '' && inputs.tags || 'type=ref,event=branch\ntype=sha,prefix={{branch}}-\ntype=semver,pattern={{version}}\ntype=raw,value=latest,enable={{is_default_branch}}' }}
86120

87121
- name: Build and push Docker image
88122
id: build
89123
uses: docker/build-push-action@v4
90124
with:
91125
context: ${{ inputs.context }}
92126
file: ${{ inputs.dockerfile }}
127+
platforms: ${{ inputs.platforms }}
93128
push: ${{ inputs.push }}
94129
tags: ${{ steps.meta.outputs.tags }}
95130
labels: ${{ steps.meta.outputs.labels }}
96-
cache-from: ${{ inputs.cache == 'true' && 'type=gha' || '' }}
97-
cache-to: ${{ inputs.cache == 'true' && format('type=gha,mode=max,key={0}', steps.cache-key.outputs.key) || '' }}
131+
cache-from: ${{ inputs.cache == 'true' && format('type=gha,scope={0}', inputs.cache-scope != '' && inputs.cache-scope || inputs.image-name) || '' }}
132+
cache-to: ${{ inputs.cache == 'true' && format('type=gha,mode=max,scope={0}', inputs.cache-scope != '' && inputs.cache-scope || inputs.image-name) || '' }}
98133
build-args: |
99134
BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
100135
VCS_REF=${{ github.sha }}
101136
VERSION=${{ github.ref_name }}
137+
${{ inputs.build-args }}
102138
103139
- name: Run Trivy vulnerability scan
104140
id: trivy
@@ -108,7 +144,8 @@ runs:
108144
image-ref: ${{ steps.meta.outputs.tags }}
109145
format: "sarif"
110146
output: "trivy-results.sarif"
111-
severity: "CRITICAL,HIGH"
147+
severity: ${{ inputs.scan-severity }}
148+
exit-code: ${{ inputs.scan-exit-code }}
112149
continue-on-error: true
113150

114151
- name: Upload Trivy results

.github/actions/ecs/deploy/action.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
###############################################################################
2+
# composite action: ecs/deploy
3+
#
4+
# Renders a new ECS task definition from a base JSON template with updated
5+
# image URIs, registers the new task definition, and updates the ECS service
6+
# to trigger a rolling deployment.
7+
#
8+
# Callers: release.yml (deploy-production job)
9+
# Inputs: cluster, service, task-definition, container-name, image
10+
###############################################################################
111
name: "ECS Deploy"
212
description: "Deploy updated task definition to ECS Fargate service"
313

@@ -76,7 +86,6 @@ runs:
7686
service: ${{ inputs.service }}
7787
cluster: ${{ inputs.cluster }}
7888
wait-for-service-stability: ${{ inputs.wait-for-stability }}
79-
wait-for-service-stability-timeout: ${{ inputs.timeout-seconds }}
8089

8190
- name: Verify deployment
8291
shell: bash
Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,30 @@
1-
name: "Publish Pytest Results"
2-
description: "Upload pytest junit xml"
1+
###############################################################################
2+
# composite action: publish-test-results
3+
#
4+
# Uploads JUnit XML test result files as a workflow artifact so they are
5+
# visible in the GitHub Actions UI and retained for post-run analysis.
6+
#
7+
# Callers: ci.yml (backend-ci job)
8+
# Inputs: files (glob pattern), check_name (artifact display name)
9+
###############################################################################
10+
name: "Publish Test Results"
11+
description: "Upload JUnit XML test results as a workflow artifact"
12+
13+
inputs:
14+
files:
15+
description: "Glob pattern(s) for JUnit XML files (newline-separated)"
16+
required: true
17+
check_name:
18+
description: "Artifact name shown in the Actions UI"
19+
required: false
20+
default: "Test Results"
321

422
runs:
523
using: "composite"
624
steps:
725
- name: Upload test results
826
uses: actions/upload-artifact@v4
927
with:
10-
name: pytest-results
11-
path: backend/test-results.xml
28+
name: ${{ inputs.check_name }}
29+
path: ${{ inputs.files }}
30+
if-no-files-found: warn

0 commit comments

Comments
 (0)