-
Notifications
You must be signed in to change notification settings - Fork 0
207 lines (179 loc) · 6.49 KB
/
Copy pathdeploy.yml
File metadata and controls
207 lines (179 loc) · 6.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
name: Build and Deploy to AWS
on:
push:
branches:
- main
# Only trigger when actual code or config changes — not docs, markdown etc.
paths:
- 'src/**'
- 'build.gradle'
- 'settings.gradle'
- 'Dockerfile'
- 'infra/**'
- '.github/workflows/**'
workflow_dispatch:
inputs:
environment:
description: 'Deployment environment'
required: true
default: 'production'
type: choice
options:
- production
env:
AWS_REGION: us-east-2
ECR_REPOSITORY: ga4gh-impl-registry
STACK_NAME: ga4gh-impl-registry
jobs:
build-and-push:
runs-on: ubuntu-latest
outputs:
image-uri: ${{ steps.image.outputs.image-uri }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v3
with:
java-version: '21'
distribution: 'temurin'
cache: gradle
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: src/main/frontend/package-lock.json
- name: Build with Gradle
run: ./gradlew build -x test --no-daemon
- name: Run tests
if: false
run: ./gradlew test --no-daemon
- name: Generate test coverage
if: false
run: ./gradlew jacocoTestReport --no-daemon
- name: Setting Up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Create ECR repository if it does not exist
run: |
aws ecr describe-repositories \
--repository-names ${{ env.ECR_REPOSITORY }} \
--region ${{ env.AWS_REGION }} 2>/dev/null || \
aws ecr create-repository \
--repository-name ${{ env.ECR_REPOSITORY }} \
--region ${{ env.AWS_REGION }} \
--image-scanning-configuration scanOnPush=true \
--image-tag-mutability MUTABLE
- name: Get next version from ECR
id: versioning
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
run: |
TAGS=$(aws ecr list-images \
--repository-name $ECR_REPOSITORY \
--query 'imageIds[*].imageTag' \
--output text 2>/dev/null | tr '\t' '\n' \
| grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' \
| sort -V \
| tail -1)
echo "Latest version found: $TAGS"
if [ -z "$TAGS" ]; then
NEXT_VERSION="0.1.0"
else
MAJOR=$(echo $TAGS | cut -d. -f1)
MINOR=$(echo $TAGS | cut -d. -f2)
PATCH=$(echo $TAGS | cut -d. -f3)
NEXT_VERSION="$MAJOR.$MINOR.$((PATCH + 1))"
fi
echo "Next version: $NEXT_VERSION"
echo "version=${NEXT_VERSION}" >> $GITHUB_ENV
- name: Build and Push to ECR
uses: docker/build-push-action@v2
with:
context: .
builder: ${{ steps.buildx.outputs.name }}
file: ./Dockerfile
push: true
tags: |
${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${{ env.version }}
${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Set Image URI output
id: image
run: |
echo "image-uri=${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${{ env.version }}" >> $GITHUB_OUTPUT
deploy-production:
needs: build-and-push
runs-on: ubuntu-latest
environment:
name: production
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Deploy CloudFormation stack
run: |
aws cloudformation deploy \
--template-file ./infra/cloudformation-template.yaml \
--stack-name ${{ env.STACK_NAME }} \
--parameter-overrides \
Environment=production \
ImageUri=${{ needs.build-and-push.outputs.image-uri }} \
DatabasePassword=${{ secrets.DB_PASSWORD }} \
--capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM \
--no-fail-on-empty-changeset
- name: Wait for stack update
run: |
aws cloudformation wait stack-create-complete \
--stack-name ${{ env.STACK_NAME }} 2>/dev/null || \
aws cloudformation wait stack-update-complete \
--stack-name ${{ env.STACK_NAME }}
- name: Get stack outputs
run: |
aws cloudformation describe-stacks \
--stack-name ${{ env.STACK_NAME }} \
--query 'Stacks[0].Outputs' \
--output table
- name: Post deployment summary
run: |
APP_URL=$(aws cloudformation describe-stacks \
--stack-name ${{ env.STACK_NAME }} \
--query "Stacks[0].Outputs[?OutputKey=='ApplicationURL'].OutputValue" \
--output text)
echo "## Production Deployment Successful" >> $GITHUB_STEP_SUMMARY
echo "| Key | Value |" >> $GITHUB_STEP_SUMMARY
echo "| --- | ----- |" >> $GITHUB_STEP_SUMMARY
echo "| Stack | ${{ env.STACK_NAME }} |" >> $GITHUB_STEP_SUMMARY
echo "| Region | ${{ env.AWS_REGION }} |" >> $GITHUB_STEP_SUMMARY
echo "| Image | ${{ needs.build-and-push.outputs.image-uri }} |" >> $GITHUB_STEP_SUMMARY
echo "| App URL | $APP_URL |" >> $GITHUB_STEP_SUMMARY
notify:
needs: [build-and-push, deploy-production]
runs-on: ubuntu-latest
if: always()
steps:
- name: Check deployment status
run: |
if [ "${{ needs.deploy-production.result }}" == "success" ]; then
echo "✅ Deployment successful!"
exit 0
else
echo "❌ Deployment failed!"
exit 1
fi