-
Notifications
You must be signed in to change notification settings - Fork 15
149 lines (138 loc) · 6.3 KB
/
Copy pathbuild.yml
File metadata and controls
149 lines (138 loc) · 6.3 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
name: Build
on:
push:
branches: ['**']
tags: ['v*']
# Manual escape hatch (e.g. when push webhooks are throttled during a
# GitHub Actions incident). Run from the Actions UI:
# - select a `vX.Y.Z` tag ref -> release build of that tag, OR
# - run from a branch and pass `tag: vX.Y.Z` -> release build that
# creates/attaches the release to that tag.
# Leave `tag` blank on a branch run for a plain dev build (artifact).
workflow_dispatch:
inputs:
tag:
description: 'Release tag to build (e.g. v2.0.0). Blank = dev build.'
required: false
default: ''
permissions:
contents: write
jobs:
# Decide which runner the build lands on. `runs-on` is fixed before a job
# starts and a job pointed at an offline self-hosted runner queues forever
# instead of failing over — so we probe first and hand the label down.
pick-runner:
runs-on: ubuntu-latest
outputs:
label: ${{ steps.pick.outputs.label }}
steps:
- name: Probe for an online self-hosted runner
id: pick
env:
# Listing runners needs repo-admin access; the default GITHUB_TOKEN
# does NOT have it. Create a PAT (classic: `repo`; fine-grained:
# Administration → read) and store it as the RUNNER_CHECK_TOKEN
# secret. If the secret is missing, we fall back to windows-latest.
GH_TOKEN: ${{ secrets.RUNNER_CHECK_TOKEN }}
run: |
label=windows-latest
if [ -n "$GH_TOKEN" ]; then
online=$(gh api "repos/${{ github.repository }}/actions/runners" \
--jq '[.runners[] | select(.status=="online") | select([.labels[].name] | index("self-hosted"))] | length' \
2>/dev/null || echo 0)
if [ "${online:-0}" -gt 0 ]; then
label=self-hosted
fi
fi
echo "Selected runner: $label"
echo "label=$label" >> "$GITHUB_OUTPUT"
build:
needs: pick-runner
runs-on: ${{ needs.pick-runner.outputs.label }}
# Windows PowerShell 5.1 is always present; the runner's default `pwsh`
# (PowerShell Core) is not installed by default, and `shell: bash` on a
# self-hosted box resolves to the WSL launcher in System32.
defaults:
run:
shell: powershell
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
# Resolve the effective version once so every step below agrees.
# is_release=true when a vX.Y.Z tag is in play (pushed tag,
# dispatched-from-tag, or a `tag` input); the embedded addon's
# `## Version:` and the compiled CLASSIC_API_VERSION are both
# stamped from it at embed/compile time (see cmake/embed_addon.cmake)
# — no source edit.
- name: Resolve version
id: ver
env:
INPUT_TAG: ${{ inputs.tag }}
run: |
if ($env:GITHUB_EVENT_NAME -eq 'workflow_dispatch' -and $env:INPUT_TAG) {
$tag = $env:INPUT_TAG
} elseif ($env:GITHUB_REF -like 'refs/tags/v*') {
$tag = $env:GITHUB_REF_NAME
} else {
$tag = ''
}
$isRelease = if ($tag) { 'true' } else { 'false' }
Add-Content -Path $env:GITHUB_OUTPUT -Value "tag=$tag" -Encoding utf8
Add-Content -Path $env:GITHUB_OUTPUT -Value "is_release=$isRelease" -Encoding utf8
- name: Configure (release)
if: steps.ver.outputs.is_release == 'true'
run: cmake -B build -A Win32 "-DCLASSICAPI_TAG=${{ steps.ver.outputs.tag }}"
- name: Configure (dev)
if: steps.ver.outputs.is_release != 'true'
run: cmake -B build -A Win32
- name: Build
run: cmake --build build --config Release
# Dev builds carry their own symbols. With the PDB sitting next to the DLL
# the client's crash handler resolves our frames to file and line — a
# tester's log reads `Texture::Mask::PrimIndexed_h+12 (Mask.cpp,246)`
# instead of a bare address — and the map resolves `0001:offset` addresses
# by hand when there is no dump. Both match THIS build and nothing else,
# which is why they travel with it rather than being rebuilt later from the
# same commit. Unlike the release bundle these need no off-putting name:
# the artifact is behind the Actions UI, so whoever downloads it is already
# the audience for symbols.
- name: Upload artifact
if: steps.ver.outputs.is_release != 'true'
uses: actions/upload-artifact@v4
with:
name: ClassicAPI-${{ github.sha }}
# Shared parent is build/Release, so all three land at the zip root.
path: |
build/Release/ClassicAPI.dll
build/Release/ClassicAPI.pdb
build/Release/ClassicAPI.map
# A symbol-less artifact looks identical to a good one until someone
# needs a stack out of it, so fail the build instead of warning.
if-no-files-found: error
# Bundle both debug artifacts into one zip so a crash from a shipped DLL
# can be triaged exactly. The PDB gives WinDbg/x64dbg/VS a line-level
# symbolicated call stack from a crash dump; the map resolves the
# `0001:offset` addresses in WoW's ERROR #132 crash log by hand when no
# dump is available. Both match THIS exact DLL build.
# The filename is deliberately off-putting: it is NOT the addon and has no
# value to a normal player. The loud all-caps name keeps them from
# grabbing it by mistake; the tag suffix lets a dev match symbols to the
# exact build. (pdb/map keep their real names inside so the pdb signature
# still lines up with the DLL.)
- name: Package debug symbols for release
if: steps.ver.outputs.is_release == 'true'
run: >
Compress-Archive
-Path build/Release/ClassicAPI.pdb, build/Release/ClassicAPI.map
-DestinationPath build/Release/Crash-Symbols-Use-For-Debugging-${{ steps.ver.outputs.tag }}.zip
-Force
- name: Release
if: steps.ver.outputs.is_release == 'true'
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.ver.outputs.tag }}
files: |
build/Release/ClassicAPI.dll
build/Release/Crash-Symbols-Use-For-Debugging-${{ steps.ver.outputs.tag }}.zip
generate_release_notes: true