Skip to content

Commit c16f3c3

Browse files
committed
chore: rewrite ecamp3 deployment to helmfile
That it is easier to use github action secrets and vars in the deployment. Leave dev and stage-prod in separate files that the review is somehow easier. They will be put into one workflow in the next commit. The default false for the num_threads is currently a hack because the if statement in the secret should be an if empty, not just if. There we should move the default into the application code, and then we can simplify the null handling. Also add api.dataMigrationsDir as an explicit value. This was implicit before. There we should also move the default to the application code later. I leave these improvements out that this PR remains reviewable. It's also best to diff the deleted values.yaml and the values.yaml.gotmpl. Sadly the similarity was not enough for git to mark this as rename.
1 parent fd9568b commit c16f3c3

19 files changed

+740
-585
lines changed

.github/workflows/deployment-devel.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ on:
55
branches:
66
- devel
77
workflow_dispatch:
8+
inputs:
9+
action:
10+
description: "Choose action"
11+
type: choice
12+
required: true
13+
default: diff
14+
options:
15+
- diff
16+
- deploy
817

918
jobs:
1019
continuous-integration:
@@ -29,4 +38,5 @@ jobs:
2938
with:
3039
name: dev
3140
env: dev
32-
secrets: inherit
41+
action: ${{ github.event.inputs.action || 'deploy' }}
42+
secrets: inherit

.github/workflows/deployment-pr.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@ name: CD for feature branches
33
on:
44
pull_request_target:
55
types: [opened, reopened, labeled, synchronize]
6+
workflow_dispatch:
7+
inputs:
8+
action:
9+
description: "Choose action"
10+
type: choice
11+
required: true
12+
default: diff
13+
options:
14+
- diff
15+
- deploy
616

717
concurrency:
818
group: ${{ github.workflow}}-${{ github.event.pull_request.number }}
@@ -30,4 +40,5 @@ jobs:
3040
env: feature-branch
3141
pr-number: ${{ github.event.pull_request.number }}
3242
dropDBOnUninstall: true
43+
action: ${{ github.event.inputs.action || 'deploy' }}
3344
secrets: inherit

.github/workflows/deployment-stage-prod.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@ on:
99
- staging
1010
- prod
1111
workflow_dispatch:
12+
inputs:
13+
action:
14+
description: "Choose action"
15+
type: choice
16+
required: true
17+
default: diff
18+
options:
19+
- diff
20+
- deploy
1221

1322
jobs:
1423
build-and-push:
@@ -25,4 +34,8 @@ jobs:
2534
name: Upgrade or install deployment
2635
needs: build-and-push
2736
uses: ./.github/workflows/reusable-stage-prod-deployment.yml
37+
with:
38+
name: ${{ github.ref_name }}
39+
env: ${{ github.ref_name }}
40+
action: ${{ github.event.inputs.action || 'deploy' }}
2841
secrets: inherit

.github/workflows/restore-backup-dev-pr.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ on:
2121
description: The environment, if name is dev then dev, else feature-branch
2222
required: true
2323
default: dev
24+
action:
25+
description: "Choose action"
26+
type: choice
27+
required: true
28+
default: diff
29+
options:
30+
- diff
31+
- deploy
2432

2533

2634
jobs:
@@ -44,4 +52,5 @@ jobs:
4452
pr-number: ${{ inputs.pr-number }}
4553
dropDBOnUninstall: ${{ inputs.pr-number != null }}
4654
restoreSourceFile: ${{ inputs.restoreSourceFile }}
55+
action: ${{ github.event.inputs.action }}
4756
secrets: inherit

.github/workflows/restore-backup-stage-prod.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ on:
1818
and restore the database with the given backup file?
1919
Repeat the branch name to confirm. (e.g. staging or prod)
2020
required: true
21+
action:
22+
description: "Choose action"
23+
type: choice
24+
required: true
25+
default: diff
26+
options:
27+
- diff
28+
- deploy
2129

2230
jobs:
2331
check-parameters:
@@ -49,4 +57,6 @@ jobs:
4957
uses: ./.github/workflows/reusable-stage-prod-deployment.yml
5058
with:
5159
restoreSourceFile: ${{ inputs.restoreSourceFile }}
60+
env: ${{ github.ref_name }}
61+
action: ${{ github.event.inputs.action }}
5262
secrets: inherit

.github/workflows/reusable-dev-deployment.yml

Lines changed: 62 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
name: '[reusable only] Development deployment'
1+
name: '[reusable only] ecamp3 deployment'
22

33
on:
44
workflow_call:
55
inputs:
66
name:
7-
required: true
7+
description: Deployment short name for subdomain (e.g. dev, pr123).
8+
required: false
89
type: string
910
sha:
1011
required: false
1112
type: string
1213
default: ${{ github.sha }}
1314
env:
15+
description: Target environment (dev, feature-branch, staging, prod)
1416
required: true
1517
type: string
1618
pr-number:
@@ -23,15 +25,26 @@ on:
2325
restoreSourceFile:
2426
required: false
2527
type: string
28+
action:
29+
description: "Choose action of (diff|deploy)"
30+
type: string
31+
required: true
32+
default: diff
33+
34+
env:
35+
NAME: ${{ inputs.name }}
36+
IMAGE_TAG: ${{ inputs.sha }}
37+
HELM_TIMEOUT: ${{ vars.HELM_TIMEOUT }}
2638

2739
jobs:
28-
dev-deployment:
40+
deploy-ecamp3:
2941
name: Deploy to Kubernetes
3042
runs-on: ubuntu-latest
3143
environment:
3244
name: ${{ inputs.env }}
3345
steps:
3446
- name: Get link to currently running job logs
47+
if: ${{ inputs.env == 'feature-branch' }}
3548
uses: Tiryoh/[email protected]
3649
id: job-url
3750
with:
@@ -44,7 +57,7 @@ jobs:
4457
with:
4558
step: start
4659
token: ${{ secrets.REPO_ACCESS_TOKEN }}
47-
env: ${{ inputs.name }}
60+
env: ${{ inputs.env }}
4861

4962
- name: Comment progress on PR
5063
uses: thollander/actions-comment-pull-request@v3
@@ -65,74 +78,51 @@ jobs:
6578
with:
6679
ref: ${{ inputs.sha }}
6780

68-
- name: Upgrade or install helm release
69-
env:
70-
never_uninstall: ${{ needs.find-prs-to-deploy.outputs.never-uninstall }}
81+
- name: Dump secrets to /tmp/secrets.json
82+
run: |
83+
cat << 'EOF' | tee /tmp/secrets.json
84+
${{ toJSON(secrets) }}
85+
EOF
86+
jq '.' /tmp/secrets.json
87+
88+
- name: Dump variables to /tmp/vars.json
89+
run: |
90+
cat << 'EOF' | tee /tmp/vars.json
91+
${{ toJSON(vars) }}
92+
EOF
93+
jq '.' /tmp/vars.json
94+
95+
- name: Merge secrets, variables, and workflow inputs to env.yaml
96+
run: |
97+
jq -n \
98+
'{
99+
NAME: "${{ inputs.name }}",
100+
IMAGE_TAG: "${{ inputs.sha }}",
101+
RESTORE_SOURCE_FILE: "${{ inputs.restoreSourceFile || '' }}",
102+
DROP_DB_ON_UNINSTALL: ${{ inputs.dropDBOnUninstall }}
103+
}' > /tmp/additions.json
104+
jq -s '.[0] + .[1] + .[2]' /tmp/secrets.json /tmp/vars.json /tmp/additions.json > .helm/ecamp3/env.yaml
105+
jq '.' .helm/ecamp3/env.yaml
106+
107+
- name: Setup kubectl authentication
108+
run: |
109+
mkdir -p ~/.kube
110+
echo '${{ secrets.KUBECONFIG }}' > ~/.kube/config
111+
chmod go-r ~/.kube/config
112+
113+
- uses: ./.github/actions/setup-helmfile
114+
115+
- name: Diff deployment
116+
run: |
117+
./.helm/ecamp3/deploy.sh diff || true
118+
119+
- name: Show values.yaml
120+
run: cat ./.helm/ecamp3/values.yaml
121+
122+
- name: Deploy
123+
if: ${{ inputs.action == 'deploy' }}
71124
run: |
72-
# Setup authentication
73-
mkdir ~/.kube && echo '${{ secrets.KUBECONFIG }}' > ~/.kube/config && chmod go-r ~/.kube/config
74-
# Switch to the helm chart directory
75-
cd .helm/ecamp3
76-
# Install dependency charts
77-
helm dependency update
78-
# Set the appVersion, workaround from https://github.com/helm/helm/issues/8194 so that we can
79-
# later find out which deployments need to be upgraded
80-
sed -i 's/^appVersion:.*$/appVersion: "${{ inputs.sha }}"/' Chart.yaml
81-
# Install or upgrade the release
82-
helm upgrade --install ecamp3-${{ inputs.name }} . \
83-
--set imageTag=${{ inputs.sha }} \
84-
--set frontend.image.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-frontend' \
85-
--set print.image.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-print' \
86-
--set api.image.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-api' \
87-
--set apiCache.image.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-varnish' \
88-
--set postgresql.dbBackupRestoreImage.repository='docker.io/${{ vars.DOCKER_HUB_USERNAME }}/ecamp3-db-backup-restore' \
89-
--set termsOfServiceLinkTemplate='https://ecamp3.ch/{lang}/tos' \
90-
--set newsLink='https://ecamp3.ch/blog' \
91-
--set helpLink='https://ecamp3.ch/faq' \
92-
--set domain=${{ inputs.name }}.${{ vars.DOMAIN }} \
93-
--set ingress.basicAuth.enabled=${{ vars.BASIC_AUTH_ENABLED || false }} \
94-
--set ingress.basicAuth.username=${{ secrets.BASIC_AUTH_USERNAME }} \
95-
--set ingress.basicAuth.password='${{ secrets.BASIC_AUTH_PASSWORD }}' \
96-
--set apiCache.enabled=${{ vars.API_CACHE_ENABLED || false }} \
97-
--set apiCache.sendXKeyHeadersDownstream=${{ vars.SEND_XKEY_HEADERS_DOWNSTREAM != null && format('''{0}''', vars.SEND_XKEY_HEADERS_DOWNSTREAM) || null }} \
98-
--set mail.dummyEnabled=true \
99-
--set postgresql.url='${{ secrets.POSTGRES_URL }}/ecamp3${{ inputs.name }}?sslmode=require' \
100-
--set postgresql.adminUrl='${{ secrets.POSTGRES_ADMIN_URL }}/ecamp3${{ inputs.name }}?sslmode=require' \
101-
--set postgresql.dropDBOnUninstall=${{ inputs.dropDBOnUninstall }} \
102-
--set postgresql.backup.schedule=${{ vars.BACKUP_SCHEDULE != null && format('''{0}''', vars.BACKUP_SCHEDULE) || null }} \
103-
--set postgresql.backup.s3.endpoint='${{ vars.BACKUP_S3_ENDPOINT }}' \
104-
--set postgresql.backup.s3.bucket='${{ vars.BACKUP_S3_BUCKET }}' \
105-
--set postgresql.backup.s3.accessKeyId='${{ secrets.BACKUP_S3_ACCESS_KEY_ID }}' \
106-
--set postgresql.backup.s3.accessKey='${{ secrets.BACKUP_S3_ACCESS_KEY }}' \
107-
--set postgresql.backup.encryptionKey=${{ secrets.BACKUP_ENCRYPTION_KEY != null && format('''{0}''', secrets.BACKUP_ENCRYPTION_KEY) || null }} \
108-
--set postgresql.restore.sourceFile=${{ inputs.restoreSourceFile != null && format('''{0}''', inputs.restoreSourceFile) || null }} \
109-
--set postgresql.restore.sourceAppName=${{ vars.RESTORE_SOURCE_APP != null && format('''{0}''', vars.RESTORE_SOURCE_APP) || null }} \
110-
--set postgresql.restore.s3.endpoint='${{ vars.RESTORE_S3_ENDPOINT }}' \
111-
--set postgresql.restore.s3.bucket='${{ vars.RESTORE_S3_BUCKET }}' \
112-
--set postgresql.restore.s3.accessKeyId='${{ secrets.RESTORE_S3_ACCESS_KEY_ID }}' \
113-
--set postgresql.restore.s3.accessKey='${{ secrets.RESTORE_S3_ACCESS_KEY }}' \
114-
--set postgresql.restore.encryptionKey=${{ secrets.RESTORE_ENCRYPTION_KEY != null && format('''{0}''', secrets.RESTORE_ENCRYPTION_KEY) || null }} \
115-
--set api.dataMigrationsDir='${{ vars.DATA_MIGRATIONS_DIR }}' \
116-
--set api.appSecret='${{ secrets.API_APP_SECRET }}' \
117-
--set api.sentryDsn='${{ secrets.API_SENTRY_DSN }}' \
118-
--set api.jwt.passphrase='${{ secrets.JWT_PASSPHRASE }}' \
119-
--set api.jwt.publicKey='${{ secrets.JWT_PUBLIC_KEY }}' \
120-
--set api.jwt.privateKey='${{ secrets.JWT_PRIVATE_KEY }}' \
121-
--set frontend.sentryDsn='${{ secrets.FRONTEND_SENTRY_DSN }}' \
122-
--set print.sentryDsn='${{ secrets.PRINT_SENTRY_DSN }}' \
123-
--set print.browserWsEndpoint='${{ secrets.BROWSER_WS_ENDPOINT }}' \
124-
--set print.ingress.readTimeoutSeconds='${{ vars.PRINT_INGRESS_READ_TIMEOUT_SECONDS }}' \
125-
--set print.renderHTMLTimeoutMs='${{ vars.PRINT_RENDER_HTML_TIMEOUT_MS }}' \
126-
--set print.renderPDFTimeoutMs='${{ vars.PRINT_RENDER_PDF_TIMEOUT_MS }}' \
127-
--set browserless.connectionTimeout=${{ vars.BROWSERLESS_CONNECTION_TIMEOUT_MS || '30000' }} \
128-
--set deploymentTime="$(date -u +%s)" \
129-
--set deployedVersion="$(git rev-parse --short '${{ inputs.sha }}')" \
130-
--set recaptcha.siteKey='${{ secrets.RECAPTCHA_SITE_KEY }}' \
131-
--set recaptcha.secret='${{ secrets.RECAPTCHA_SECRET }}' \
132-
--set frontend.loginInfoTextKey=${{ vars.LOGIN_INFO_TEXT_KEY }} \
133-
--set featureToggle.developer=true \
134-
--set featureToggle.checklist=${{ vars.FEATURE_CHECKLIST || 'false' }} \
135-
--timeout ${{ vars.HELM_TIMEOUT || '5m0s' }}
125+
./.helm/ecamp3/deploy.sh deploy
136126
137127
- name: Finish the GitHub deployment
138128
uses: bobheadxi/[email protected]
@@ -142,7 +132,7 @@ jobs:
142132
token: ${{ secrets.REPO_ACCESS_TOKEN }}
143133
status: ${{ job.status }}
144134
deployment_id: ${{ steps.deployment.outputs.deployment_id }}
145-
env_url: https://${{ inputs.name }}.${{ vars.DOMAIN }}
135+
env_url: ${{ (inputs.env == 'staging' || inputs.env == 'prod') && format('https://{0}.{1}', vars.SUBDOMAIN, vars.DOMAIN) || format('https://{0}.{1}', inputs.name, vars.DOMAIN) }}
146136
env: ${{ steps.deployment.outputs.env }}
147137

148138
- name: Get current time

0 commit comments

Comments
 (0)