-
Notifications
You must be signed in to change notification settings - Fork 0
136 lines (116 loc) · 4.73 KB
/
deploy.yml
File metadata and controls
136 lines (116 loc) · 4.73 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
name: Deploy to Production
on:
push:
branches: [main]
workflow_dispatch:
inputs:
force_deploy:
description: "Force deploy backend + frontend"
type: boolean
default: false
concurrency:
group: deploy-main
cancel-in-progress: false
env:
REGISTRY: ghcr.io
DEPLOY_DIR: /opt/banktracker/BankTrackerGraphQL
jobs:
changes:
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
pull-requests: read
steps:
- uses: actions/checkout@v6
with:
sparse-checkout: |
.github/pr-filter.yml
- uses: dorny/paths-filter@v3
id: filter
with:
filters: .github/pr-filter.yml
outputs:
frontend: ${{ steps.filter.outputs.frontend }}
backend: ${{ steps.filter.outputs.backend }}
backendLibrary: ${{ steps.filter.outputs.backendLibrary }}
backendData: ${{ steps.filter.outputs.backendData }}
build-backend-image:
name: Build and Push Backend Image
uses: ./.github/workflows/build-backend-image.yml
needs: changes
if: ${{ inputs.force_deploy == true || needs.changes.outputs.backend == 'true' || needs.changes.outputs.backendLibrary == 'true' || needs.changes.outputs.backendData == 'true' }}
permissions:
contents: read
packages: write
build-frontend-image:
name: Build and Push Frontend Image
uses: ./.github/workflows/build-frontend-image.yml
needs: changes
if: ${{ inputs.force_deploy == true || needs.changes.outputs.frontend == 'true' }}
permissions:
contents: read
packages: write
deploy:
name: Deploy to Production
runs-on: ubuntu-latest
needs: [build-backend-image, build-frontend-image]
if: always() && (needs.build-backend-image.result == 'success' || needs.build-frontend-image.result == 'success' || needs.build-backend-image.result == 'skipped' || needs.build-frontend-image.result == 'skipped')
permissions:
contents: read
packages: read
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Connect to Tailscale
uses: tailscale/github-action@v4
with:
oauth-client-id: ${{ secrets.TAILSCALE_OAUTH_CLIENTID }}
oauth-secret: ${{ secrets.TAILSCALE_OAUTH_CLIENT_SECRET }}
tags: tag:ci
hostname: banktracker-ci-${{ github.run_id }}
- name: Configure SSH target
id: ssh
run: |
TARGET="${{ secrets.TAILSCALE_SSH_TARGET }}"
if [[ -z "$TARGET" ]]; then
echo "::error::TAILSCALE_SSH_TARGET secret is not set"
exit 1
fi
echo "target=$TARGET" >> "$GITHUB_OUTPUT"
- name: Test connectivity
run: |
tailscale ssh "${{ steps.ssh.outputs.target }}" "echo 'Connected'"
- name: Clean up old Docker images
run: |
tailscale ssh "${{ steps.ssh.outputs.target }}" \
"docker system prune -af --filter 'until=24h'"
- name: Log in to GitHub Container Registry
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | tailscale ssh "${{ steps.ssh.outputs.target }}" \
"docker login ghcr.io -u ${{ github.actor }} --password-stdin"
- name: Pull latest images
run: |
tailscale ssh "${{ steps.ssh.outputs.target }}" \
"cd $DEPLOY_DIR && docker compose pull"
- name: Deploy all services
run: |
tailscale ssh "${{ steps.ssh.outputs.target }}" \
"cd $DEPLOY_DIR && docker compose up -d --wait"
- name: Verify deployment
if: success()
run: |
tailscale ssh "${{ steps.ssh.outputs.target }}" "cd $DEPLOY_DIR && docker compose ps"
# this job is the required branch protection rule
completed:
runs-on: ubuntu-latest
if: always()
needs: # list all the required jobs here!
- changes
- build-backend-image
- build-frontend-image
- deploy
steps:
- name: Fail
run: echo "::error::A required deployment step failed" && exit 1
if: ${{ contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'failure') || contains(needs.*.result, 'error') }}