-
Notifications
You must be signed in to change notification settings - Fork 0
356 lines (297 loc) · 11.3 KB
/
build-deploy.yml
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
name: Marathon Frontend - Build & Deploy
on:
push:
# Publish `master` as Docker `latest` image.
branches:
- dev
# - staging
- master
# Publish `v1.2.3` tags as releases.
tags:
- v*
# Run tests for any PRs.
pull_request:
env:
# TODO: Change variable to your image's name.
IMAGE_NAME: marathon-frontend
# GITHUB_TOKEN
# DOCKER_BUILD_ARGS:
# SSH_HOST:
# SSH_PORT:
DEPLOY_USERNAME: ${{ secrets.DEPLOY_USERNAME }}
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
# APP_PATH:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
# SENTRY_ENVIRONMENT:
jobs:
# Notify Slack Starting
notify_slack_starting:
name: Notify Slack Starting
runs-on: ubuntu-latest
continue-on-error: true
# Only notify Start/Success on Push
if: "github.event_name == 'push' && !contains(github.ref, 'refs/tags') && !contains(github.event.head_commit.message, '#skip-ci')"
steps:
- name: Notify Slack Starting
id: slack
continue-on-error: true
uses: voxmedia/github-action-slack-notify-build@v1
env:
SLACK_BOT_TOKEN: ${{ env.SLACK_BOT_TOKEN }}
with:
channel: ${{ env.SLACK_CHANNEL }}
status: STARTING (${{ github.actor }})
color: warning
# Run tests.
# See also https://docs.docker.com/docker-hub/builds/automated-testing/
test:
name: Test
runs-on: ubuntu-latest
steps:
# - uses: actions/checkout@v2
# - name: Run tests
# run: |
# if [ -f docker-compose.test.yml ]; then
# docker-compose --file docker-compose.test.yml build
# docker-compose --file docker-compose.test.yml run sut
# else
# docker build . --file Dockerfile
# fi
- name: Run tests
id: test
run: |
echo 'testing'
- name: Notify slack fail
continue-on-error: true
if: failure()
env:
SLACK_BOT_TOKEN: ${{ env.SLACK_BOT_TOKEN }}
uses: voxmedia/github-action-slack-notify-build@v1
with:
channel: ${{ env.SLACK_CHANNEL }}
status: FAILED
color: danger
# Push image to GitHub Packages.
# See also https://docs.docker.com/docker-hub/builds/
push:
# Ensure test job passes before pushing image.
needs: test
name: Build & Push Docker Image
runs-on: ubuntu-latest
# Release/tag use last commit message
# So trigger on a tag even if commit message includes #skip-ci
if: "(github.event_name == 'push' && !contains(github.event.head_commit.message, '#skip-ci') || contains(github.ref, 'refs/tags'))"
steps:
- name: checkout source
uses: actions/checkout@v2
- name: generate lfs file list
run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id
- name: restore lfs cache
uses: actions/cache@v2
id: lfs-cache
with:
path: .git/lfs
key: ${{ runner.os }}-lfs-${{ hashFiles('.lfs-assets-id') }}-v1
- name: pull lfs files
run: git lfs pull
# - name: Checkout github repo (+ download lfs dependencies)
# uses: actions/checkout@v2
# with:
# lfs: true
# - name: Checkout LFS objects
# run: git lfs checkout
- name: Extract branch name
id: extract_branch
shell: bash
run: echo "##[set-output name=branch;]$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')"
- name: Extract branch version
id: extract_version
run: |
BRANCH=${{steps.extract_branch.outputs.branch}}
# IMAGE_ID=docker.pkg.github.com/${{ github.repository }}/$IMAGE_NAME
IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME
# Change all uppercase to lowercase
IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
VERSION=$BRANCH
# Strip "v" prefix from tag name
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
# Use Docker `latest` tag convention
[ "$VERSION" == "master" ] && VERSION=latest
echo ::set-output name=IMAGE_ID::$IMAGE_ID
echo ::set-output name=VERSION::$VERSION
- name: Set Variables
id: set_vars
shell: bash
run: |
BRANCH=${{steps.extract_branch.outputs.branch}}
IMAGE_ID=${{steps.extract_version.outputs.IMAGE_ID}}
VERSION=${{steps.extract_version.outputs.VERSION}}
TAGS=$IMAGE_ID:$VERSION
if [[ $BRANCH == 'dev' ]]; then
# quotes are SUPER IMPORTANT to handle multiline vars
DOCKER_BUILD_ARGS="${{ secrets.DEV_DOCKER_BUILD_ARGS }}"
elif [[ $BRANCH == 'staging' ]]; then
# quotes are SUPER IMPORTANT to handle multiline vars
DOCKER_BUILD_ARGS="${{ secrets.STAGING_DOCKER_BUILD_ARGS }}"
elif [[ $BRANCH == 'master' ]]; then
# quotes are SUPER IMPORTANT to handle multiline vars
DOCKER_BUILD_ARGS="${{ secrets.PROD_DOCKER_BUILD_ARGS }}"
fi
# set-output breaks multiline values
# so we escape them before passing them on
DOCKER_BUILD_ARGS="${DOCKER_BUILD_ARGS//'%'/'%25'}"
DOCKER_BUILD_ARGS="${DOCKER_BUILD_ARGS//$'\n'/'%0A'}"
DOCKER_BUILD_ARGS="${DOCKER_BUILD_ARGS//$'\r'/'%0D'}"
echo ::set-output name=DOCKER_BUILD_ARGS::$DOCKER_BUILD_ARGS
echo ::set-output name=TAGS::$TAGS
echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to GitHub Container Registry
uses: docker/login-action@v1
with:
# registry: docker.pkg.github.com
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ steps.set_vars.outputs.TAGS }}
build-args: ${{ steps.set_vars.outputs.DOCKER_BUILD_ARGS }}
labels: |
org.opencontainers.image.source=${{ github.event.repository.clone_url }}
org.opencontainers.image.created=${{ steps.set_vars.outputs.created }}
org.opencontainers.image.revision=${{ github.sha }}
- name: Notify slack fail
continue-on-error: true
if: failure()
env:
SLACK_BOT_TOKEN: ${{ env.SLACK_BOT_TOKEN }}
uses: voxmedia/github-action-slack-notify-build@v1
with:
channel: ${{ env.SLACK_CHANNEL }}
status: FAILED
color: danger
deploy:
needs: push
name: Deploy to Server
runs-on: ubuntu-latest
# only deploy on push branches, not on releases/tags
if: "github.event_name == 'push' && !contains(github.ref, 'refs/tags') && !contains(github.event.head_commit.message, '#skip-ci') && !contains(github.event.head_commit.message, '#skip-deploy')"
steps:
- name: Extract branch name
id: extract_branch
shell: bash
run: echo "##[set-output name=branch;]$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')"
- name: Set Variables
id: set_vars
shell: bash
run: |
BRANCH=${{steps.extract_branch.outputs.branch}}
if [[ $BRANCH == 'dev' ]]; then
SSH_HOST=${{ secrets.DEV_SSH_HOST }}
SSH_PORT=${{ secrets.DEV_SSH_PORT }}
APP_PATH=${{ secrets.DEV_PATH }}
elif [[ $BRANCH == 'staging' ]]; then
SSH_HOST=${{ secrets.STAGING_SSH_HOST }}
SSH_PORT=${{ secrets.STAGING_SSH_PORT }}
APP_PATH=${{ secrets.STAGING_PATH }}
elif [[ $BRANCH == 'master' ]]; then
SSH_HOST=${{ secrets.PROD_SSH_HOST }}
SSH_PORT=${{ secrets.PROD_SSH_PORT }}
APP_PATH=${{ secrets.PROD_PATH }}
fi
echo ::set-output name=SSH_HOST::$SSH_HOST
echo ::set-output name=SSH_PORT::$SSH_PORT
echo ::set-output name=APP_PATH::$APP_PATH
- name: Deploy to Server
id: deploy
uses: appleboy/ssh-action@master
with:
host: ${{ steps.set_vars.outputs.SSH_HOST }}
port: ${{ steps.set_vars.outputs.SSH_PORT }}
username: ${{ env.DEPLOY_USERNAME }}
key: ${{ env.DEPLOY_SSH_KEY }}
script: |
cd ${{ steps.set_vars.outputs.APP_PATH }}
docker-compose down
echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io --username ${{ github.actor }} --password-stdin
docker-compose pull
docker-compose up -d
docker image prune -f
- name: Notify slack fail
continue-on-error: true
if: failure()
env:
SLACK_BOT_TOKEN: ${{ env.SLACK_BOT_TOKEN }}
uses: voxmedia/github-action-slack-notify-build@v1
with:
channel: ${{ env.SLACK_CHANNEL }}
status: FAILED
color: danger
# Notify Slack of Success
notify_slack_success:
needs: deploy
name: Notify Slack of Success
runs-on: ubuntu-latest
continue-on-error: true
# Only notify Start/Success on Push
if: "github.event_name == 'push' && !contains(github.ref, 'refs/tags') && !contains(github.event.head_commit.message, '#skip-ci')"
steps:
- name: Notify Slack of Success
id: slack
continue-on-error: true
uses: voxmedia/github-action-slack-notify-build@v1
env:
SLACK_BOT_TOKEN: ${{ env.SLACK_BOT_TOKEN }}
with:
channel: ${{ env.SLACK_CHANNEL }}
status: SUCCESS
color: good
notify_sentry_release:
needs: deploy
name: Notify Sentry of Release
runs-on: ubuntu-latest
continue-on-error: true
if: "github.event_name == 'push' && !contains(github.event.head_commit.message, '#skip-ci') && !contains(github.event.head_commit.message, '#skip-deploy')"
steps:
- uses: actions/checkout@v2
- name: Checkout github repo (+ download lfs dependencies)
uses: actions/checkout@v2
with:
lfs: true
- name: Checkout LFS objects
run: git lfs checkout
- name: Extract branch name
id: extract_branch
shell: bash
run: echo "##[set-output name=branch;]$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')"
- name: Set Variables
id: set_vars
shell: bash
run: |
BRANCH=${{steps.extract_branch.outputs.branch}}
if [[ $BRANCH == 'dev' ]]; then
SENTRY_ENVIRONMENT='dev'
elif [[ $BRANCH == 'staging' ]]; then
SENTRY_ENVIRONMENT='staging'
elif [[ $BRANCH == 'master' ]]; then
SENTRY_ENVIRONMENT='prod'
fi
echo ::set-output name=SENTRY_ENVIRONMENT::$SENTRY_ENVIRONMENT
- name: Create Sentry release
uses: getsentry/action-release@v1
env:
SENTRY_AUTH_TOKEN: ${{ env.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ${{ env.SENTRY_ORG }}
SENTRY_PROJECT: ${{ env.SENTRY_PROJECT }}
with:
environment: ${{ steps.set_vars.outputs.SENTRY_ENVIRONMENT }}