-
Notifications
You must be signed in to change notification settings - Fork 0
123 lines (108 loc) · 5.57 KB
/
Copy pathdeploy.yml
File metadata and controls
123 lines (108 loc) · 5.57 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
name: Deploy to Azure App Service
# Trigger only on push to master and manual dispatch.
# This is the only workflow in this repo: it builds and deploys to Azure App Service.
on:
push:
branches: [master]
workflow_dispatch:
# Cancel in-progress runs of the same workflow on the same ref.
concurrency:
group: deploy-popunkoutersoftware-${{ github.ref }}
cancel-in-progress: true
# Minimum scopes for OIDC deployment; everything else is denied.
permissions:
id-token: write
contents: read
# Most values come from the GitHub Environment "production".
# Required environment secrets/vars (configure in Settings → Environments → production):
# AZURE_CLIENT_ID (secret) — User-assigned MI for OIDC
# AZURE_TENANT_ID (secret)
# AZURE_SUBSCRIPTION_ID (secret)
# AZURE_APP_NAME (variable, optional) — App Service name.
# Falls back to the known production app if unset.
# AZURE_RESOURCE_GROUP (variable, optional) — falls back to PoPunkouterSoftware.
# AZURE_WEBAPP_SLOT (variable, optional) — default 'production'
env:
DOTNET_VERSION: '10.0.x'
DOTNET_CLI_TELEMETRY_OPTOUT: 'true'
DOTNET_NOLOGO: 'true'
# FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 keeps Azure actions on the maintained Node 24 runtime.
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'
# The live production targets. Used as the fallback when the matching
# "production" environment variables are unset or misconfigured, so the
# pipeline deploys to the right resource even without the GitHub vars.
DEFAULT_APP_NAME: 'app-popunkoutersoftware'
DEFAULT_RESOURCE_GROUP: 'PoPunkouterSoftware'
jobs:
build-and-deploy:
name: Build & Deploy
runs-on: ubuntu-latest
timeout-minutes: 20
# Pin to the production environment so its protection rules / approval gates apply.
environment: production
steps:
# Resolve the deploy targets once: prefer the production environment vars,
# fall back to the known live resources. A warning (not a hard failure) is
# emitted when a var is missing so the deploy still proceeds correctly.
- name: Resolve deploy targets
id: targets
run: |
APP_NAME="${{ vars.AZURE_APP_NAME || env.DEFAULT_APP_NAME }}"
RG="${{ vars.AZURE_RESOURCE_GROUP || env.DEFAULT_RESOURCE_GROUP }}"
if [ -z "${{ vars.AZURE_APP_NAME }}" ]; then
echo "::warning title=AZURE_APP_NAME unset::Using fallback app name '$APP_NAME'. Set AZURE_APP_NAME in Settings → Environments → production → Variables to make this explicit."
fi
echo "app_name=$APP_NAME" >> "$GITHUB_OUTPUT"
echo "resource_group=$RG" >> "$GITHUB_OUTPUT"
echo "Deploying '$APP_NAME' in resource group '$RG'."
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
fetch-depth: 0 # full history so MinVer can compute the version from tags
- name: Setup .NET ${{ env.DOTNET_VERSION }}
uses: actions/setup-dotnet@9a946fdbd5fb07b82b2f5a4466058b876ab72bb2 # v5.3.0
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Cache NuGet packages
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.nuget/packages
key: nuget-${{ runner.os }}-${{ hashFiles('**/*.csproj', 'Directory.Packages.props') }}
restore-keys: |
nuget-${{ runner.os }}-
- name: Restore
run: dotnet restore PoPunkouterSoftware.sln --nologo
- name: Build
run: dotnet build PoPunkouterSoftware.sln -c Release --no-restore --nologo
# Deliberately NO test step: this pipeline is build-and-deploy only.
# All test tiers (unit/integration/E2E) run locally before pushing to master.
- name: Publish
run: dotnet publish src/PoPunkouterSoftware/PoPunkouterSoftware.csproj -c Release --no-restore -o ./publish --nologo
# NOTE: 'secrets' is intentionally NOT referenced in any 'if:' expression —
# GitHub Actions blocks it there to avoid leaking secret existence.
# azure/login will fail with a clear error if the production environment
# is misconfigured (missing AZURE_CLIENT_ID / AZURE_TENANT_ID / AZURE_SUBSCRIPTION_ID).
- name: Azure Login (OIDC)
uses: azure/login@a457da9ea143d694b1b9c7c869ebb04ebe844ef5 # v2.3.0
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
# Infrastructure is provisioned out-of-band (infra/main.bicep, applied
# locally or by a separately-privileged infra workflow) — deliberately NOT
# here. That keeps this deploy identity scoped to website-publish only,
# rather than the resource-group Contributor that provisioning requires.
#
# NOTE: azure/webapps-deploy (OneDeploy) started returning HTTP 500 from the
# App Service intake API on 2026-07-10 across three consecutive runs, while
# the site and Kudu stayed healthy. The legacy Kudu zipdeploy path is a
# separate endpoint and unaffected, so deploy through it via the CLI.
- name: Zip publish output
run: cd publish && zip -qr ../deploy.zip .
- name: Deploy to Azure App Service (zipdeploy)
run: |
az webapp deployment source config-zip \
--resource-group "${{ steps.targets.outputs.resource_group }}" \
--name "${{ steps.targets.outputs.app_name }}" \
--src deploy.zip \
--timeout 600