Repository navigation
149 lines (138 loc) · 6.84 KB
/
Copy pathdocs-post.yml
File metadata and controls
149 lines (138 loc) · 6.84 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: docs post-merge
# Build the API documentation with Doxygen and deploy to Cloudflare Pages.
#
# Required repository secrets:
# CLOUDFLARE_API_TOKEN - token with "Cloudflare Pages: Edit" permission
# CLOUDFLARE_ACCOUNT_ID - your CF account id
#
# Required repository variables (or hard-code below):
# CF_PAGES_PROJECT - the Cloudflare Pages project name
# (defaults to "pineforge-docs" if unset)
on:
push:
branches: [main]
workflow_dispatch: {}
permissions:
contents: read
deployments: write
concurrency:
group: ${{ github.workflow }}-${{ github.run_id }}
cancel-in-progress: false
jobs:
authz:
name: authz
# Fleet routing is fixed for this workflow; releases use pf-gcp-main.
runs-on: ubuntu-24.04
permissions: {}
# No timeout-minutes: the owner's no-time-limits rule (check-no-time-limits refuses new ones).
steps:
- name: Only our own pull requests and our own events run CI
env:
EVENT: ${{ github.event_name }}
REPO: ${{ github.repository }}
HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
HEAD_IS_FORK: ${{ github.event.pull_request.head.repo.fork }}
ASSOCIATION: ${{ github.event.pull_request.author_association }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
WR_HEAD_REPO: ${{ github.event.workflow_run.head_repository.full_name }}
WR_ACTOR: ${{ github.event.workflow_run.triggering_actor.login }}
GH_TOKEN: ${{ github.token }} # read-only use: one permission lookup for workflow_run
# Bot logins whose same-repository pull requests count as ours: dependabot[bot] (CI-DEPBOT A)
# and the org's own GitHub App bot logins by name (space-separated), nothing else.
ALLOWED_BOTS: "dependabot[bot] pineforge-app[bot]"
run: |
set -eu
fail() { echo "::error title=authz::$1"; echo "authz: REFUSED: $1" >> "$GITHUB_STEP_SUMMARY"; exit 1; }
case "$EVENT" in
push|workflow_dispatch|schedule|merge_group|release|workflow_call|repository_dispatch)
# Only someone with write access to this repository (or our App's token) can cause these
# events; none of them runs pull-request code.
;;
workflow_run)
# LB-437: bind identity to the triggering run and its re-runner.
# These two App bots are fixed canon policy; ALLOWED_BOTS is PR-only.
[ -n "${WR_HEAD_REPO:-}" ] || fail "workflow_run head repository is missing"
[ -n "${WR_ACTOR:-}" ] || fail "workflow_run triggering actor is missing"
[ "$WR_HEAD_REPO" = "$REPO" ] || fail "workflow_run head repository does not match this repository"
case "$WR_ACTOR" in
"pineforge-app[bot]"|"pineforge-ci-dispatcher[bot]") ;;
*"[bot]") fail "workflow_run bot is not on the canon allowlist" ;;
*)
perm=$(gh api "repos/$REPO/collaborators/$WR_ACTOR/permission" --jq .permission 2>/dev/null) || fail "workflow_run permission lookup failed"
case "$perm" in admin|maintain|write) ;; *) fail "workflow_run triggering actor does not have write permission" ;; esac ;;
esac ;;
pull_request)
[ "$HEAD_REPO" = "$REPO" ] || fail "pull request from another repository (${HEAD_REPO:-unknown})"
[ "$HEAD_IS_FORK" = "false" ] || fail "pull request from a fork"
case "$ASSOCIATION" in
OWNER|MEMBER|COLLABORATOR) ;;
*)
case " $ALLOWED_BOTS " in
*" $PR_AUTHOR "*) ;;
*)
# A member whose org membership is private shows as CONTRIBUTOR: ask GitHub for the
# author's permission on this repository; anything but admin/maintain/write (or a
# failed call) refuses.
perm=$(gh api "repos/$REPO/collaborators/$PR_AUTHOR/permission" --jq .permission 2>/dev/null || echo none)
case "$perm" in admin|maintain|write) ;; *) fail "author ${PR_AUTHOR:-unknown} (${ASSOCIATION:-NONE}) has permission '$perm', not write, and is not an allowlisted bot" ;; esac ;;
esac ;;
esac ;;
*) fail "event $EVENT does not run CI (pull_request_target and other events are not allowed)" ;;
esac
echo "authz: allowed ($EVENT${PR_AUTHOR:+ by $PR_AUTHOR})" >> "$GITHUB_STEP_SUMMARY"
build:
needs: [authz]
runs-on: ["self-hosted", "pf-gcp-post"]
env:
CF_PROJECT: ${{ vars.CF_PAGES_PROJECT || 'pineforge-docs' }}
DEPLOY_BRANCH: ${{ github.ref_name }}
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
fetch-depth: 0 # need tags for git describe in build.sh
- name: Install doxygen 1.13 + graphviz
env:
DOXYGEN_VERSION: "1.13.2"
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends graphviz
curl -sSL "https://github.com/doxygen/doxygen/releases/download/Release_1_13_2/doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz" \
| sudo tar -xz -C /opt
sudo ln -sf "/opt/doxygen-${DOXYGEN_VERSION}/bin/doxygen" /usr/local/bin/doxygen
doxygen --version
dot -V
# Run the SEO assertion on a synthetic site before the real docs build.
# A failure stops this job. The real build also fails on warnings in the
# guarded public surface
# (the kernel / native API headers, the C API header, the C ABI header,
# the layer map and the examples). See its 3b step.
- name: Build site
shell: bash
run: |
set -euo pipefail
bash docs/build.sh --self-test-seo
bash docs/build.sh
- name: Upload artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: docs-html
path: |
docs/site/html
docs/site/doxygen-warnings.log
retention-days: 7
- name: Sanitize deploy branch name
id: deploy
run: |
# CF Pages branch names: alphanumerics, dashes, underscores, slashes.
SAFE="$(printf '%s' "$DEPLOY_BRANCH" | tr -c 'A-Za-z0-9._/-' '-')"
echo "branch=$SAFE" >> "$GITHUB_OUTPUT"
- name: Deploy to Cloudflare Pages
uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3.15.0
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: >-
pages deploy docs/site/html
--project-name=${{ env.CF_PROJECT }}
--branch=${{ steps.deploy.outputs.branch }}
--commit-dirty=true