Repository navigation
155 lines (137 loc) · 4.98 KB
/
Copy pathdeploy-api.yml
File metadata and controls
155 lines (137 loc) · 4.98 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
# PostKit Function App — Linux Consumption in rg-postkit-prod-ae.
# Target subscription: SSD Post Kit / 9b6fc2b1-064a-4eb2-81fe-0aa8c7c751b5 (via vars.AZURE_SUBSCRIPTION_ID).
# Secrets: NEVER in GitHub Secrets. OIDC → Key Vault `forwardemail-api-key`.
# Required Variables: AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_SUBSCRIPTION_ID.
# If OIDC Variables are missing, the deploy job is skipped (workflow succeeds).
name: Deploy API (Function)
on:
push:
branches: [main]
paths:
- 'apps/api/**'
- 'packages/post-kit-email/**'
- 'infra/function-app.bicep'
- 'infra/appconfig-seed.json'
- 'scripts/seed-appconfig.sh'
- 'scripts/sync-function-cors-from-appconfig.sh'
- 'scripts/platform-cors-origins.mjs'
- '.github/workflows/deploy-api.yml'
workflow_dispatch:
concurrency:
group: deploy-api-production
cancel-in-progress: false
env:
AZURE_RESOURCE_GROUP: rg-postkit-prod-ae
AZURE_LOCATION: australiaeast
AZURE_FUNCTIONAPP_NAME: ssd-postkit-api-prod-ae
AZURE_KEY_VAULT_NAME: ssd-postkit-kv-prod-ae
APP_CONFIG_NAME: ssd-postkit-appcs-prod-ae
KEY_VAULT_URI: https://ssd-postkit-kv-prod-ae.vault.azure.net
jobs:
build:
runs-on: ubuntu-latest
name: Build ZIP
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9.15.0
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- name: Install
run: pnpm install --frozen-lockfile
- name: Test API
run: pnpm --filter @singleton-sd/post-kit-api run test
- name: Stage zip
run: |
set -euo pipefail
chmod +x scripts/stage-api-zip.sh
./scripts/stage-api-zip.sh "$GITHUB_WORKSPACE/post-kit-api.zip"
- uses: actions/upload-artifact@v4
with:
name: post-kit-api-zip
path: post-kit-api.zip
if-no-files-found: error
deploy:
needs: build
if: ${{ vars.AZURE_CLIENT_ID != '' && vars.AZURE_TENANT_ID != '' && vars.AZURE_SUBSCRIPTION_ID != '' }}
runs-on: ubuntu-latest
name: Function App
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: post-kit-api-zip
- name: Azure login (OIDC)
uses: azure/login@v2
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
- name: Ensure resource group
run: |
set -euo pipefail
az group create \
--name "$AZURE_RESOURCE_GROUP" \
--location "$AZURE_LOCATION" \
--output none
- name: Deploy Function App infra
run: |
set -euo pipefail
PRINCIPAL_ID=$(az ad sp show --id "${{ vars.AZURE_CLIENT_ID }}" --query id -o tsv)
az deployment group create \
--resource-group "$AZURE_RESOURCE_GROUP" \
--template-file infra/function-app.bicep \
--name "postkit-api-${GITHUB_RUN_ID}" \
--parameters githubOidcPrincipalId="$PRINCIPAL_ID"
- name: Assert KV secrets exist
run: |
set -euo pipefail
deadline=$((SECONDS + 600))
attempt=0
required_secrets=(forwardemail-api-key recipient-hash-hmac-key)
while [ "$SECONDS" -lt "$deadline" ]; do
attempt=$((attempt + 1))
missing=0
for secret_name in "${required_secrets[@]}"; do
if ! az keyvault secret show \
--vault-name "$AZURE_KEY_VAULT_NAME" \
--name "$secret_name" \
--query name -o tsv >/dev/null; then
missing=1
break
fi
done
if [ "$missing" -eq 0 ]; then
exit 0
fi
remaining=$((deadline - SECONDS))
echo "Key Vault read not ready yet (attempt ${attempt}; ${remaining}s remaining); waiting for RBAC."
sleep 20
done
echo "Required Key Vault secrets are missing or the OIDC principal cannot read them (names only: forwardemail-api-key, recipient-hash-hmac-key)."
exit 1
- name: Seed App Configuration (missing keys only)
run: |
set -euo pipefail
chmod +x scripts/seed-appconfig.sh
./scripts/seed-appconfig.sh infra/appconfig-seed.json
- name: Sync Function App platform CORS from App Configuration
run: |
set -euo pipefail
chmod +x scripts/sync-function-cors-from-appconfig.sh
./scripts/sync-function-cors-from-appconfig.sh
- name: Zip deploy Function App
run: |
set -euo pipefail
az functionapp deployment source config-zip \
--resource-group "$AZURE_RESOURCE_GROUP" \
--name "$AZURE_FUNCTIONAPP_NAME" \
--src post-kit-api.zip