-
Notifications
You must be signed in to change notification settings - Fork 2
128 lines (120 loc) · 6.29 KB
/
Copy pathcodeboarding-sync.yml
File metadata and controls
128 lines (120 loc) · 6.29 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
# Dogfood sync mode: keep THIS repo's committed architecture baseline
# (.codeboarding/analysis.json + rendered docs) current on every push to main,
# so the PR review workflow always diffs against an up-to-date baseline.
#
# This is the ONLY baseline writer for this repo. The manual "rebuild from
# scratch" path (previously a separate refresh-baseline.yml) is now the
# workflow_dispatch + force_full input below, which runs the same tested action
# instead of a hand-rolled copy of its pipeline.
name: CodeBoarding sync
on:
push:
branches: [main]
# Loop guard: don't re-trigger on the files this workflow itself commits.
# Deliberately NOT '.codeboarding/**': that would also swallow pushes that
# only edit the user-authored .codeboarding/.codeboardingignore, which
# changes analysis scope and should regenerate the baseline. The action also
# skips re-analyzing its own bot commit as a backstop; the bot commit uses no
# [skip ci] (that would leak through squash-merges and skip real merges).
paths-ignore:
- '.codeboarding/*.md'
- '.codeboarding/analysis.json'
- '.codeboarding/codeboarding_version.json'
- '.codeboarding/health/**'
- 'docs/development/architecture.md'
workflow_dispatch:
inputs:
force_full:
description: 'Ignore the committed baseline and rebuild it from scratch (full analysis).'
type: boolean
required: false
default: false
permissions:
contents: write # commit the generated baseline + docs to main
concurrency:
# Serialize this workflow against itself: a push landing while a manual
# dispatch is mid-run must not produce two concurrent commits to main.
group: codeboarding-baseline-writers
cancel-in-progress: false
jobs:
sync:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
# Dogfood: run the action from the checked-out repo (uses: ./) so pushes to
# main exercise the action code on main, not the last published release.
# The action reads its scripts via github.action_path and checks the engine
# and target repo into subdirectories, so this local checkout is untouched.
- uses: actions/checkout@v4
# Mint the CodeBoarding GitHub App token so the baseline commit lands as
# codeboarding-review[bot] (App avatar = the CodeBoarding logo) instead of
# the generic github-actions[bot]. Mirrors the review workflow's token flow.
# Fails open: when App credentials are absent/invalid we fall back to
# github.token below, and the commit shows the default Actions identity.
# End-user repos can't reuse this — the App private key is never shipped to
# their runners; they authenticate the free tier via OIDC (see README).
- name: Detect CodeBoarding GitHub App credentials
id: codeboarding-app-config
shell: bash
env:
CLIENT_ID: ${{ vars.CODEBOARDING_APP_CLIENT_ID }}
APP_ID: ${{ vars.CODEBOARDING_APP_ID }}
PRIVATE_KEY: ${{ secrets.CODEBOARDING_APP_PRIVATE_KEY }}
run: |
client_id="${CLIENT_ID:-}"
app_id="${APP_ID:-}"
# GitHub App client IDs start with "Iv". If that value was stored in
# CODEBOARDING_APP_ID, use it as a client ID to avoid the deprecated
# app-id input path.
if [ -z "$client_id" ] && [ "${app_id#Iv}" != "$app_id" ]; then
client_id="$app_id"
app_id=""
fi
has_private_key=false
private_key_valid=false
if [ -n "$PRIVATE_KEY" ]; then
has_private_key=true
if printf '%s' "$PRIVATE_KEY" | openssl pkey -noout >/dev/null 2>&1; then
private_key_valid=true
else
echo "::warning::CODEBOARDING_APP_PRIVATE_KEY is not a valid PEM private key, so the sync commit will fall back to github-actions[bot]."
if printf '%b' "$PRIVATE_KEY" | openssl pkey -noout >/dev/null 2>&1; then
printf '%s\n' "::warning::CODEBOARDING_APP_PRIVATE_KEY looks like it contains literal \\n escapes. Store the downloaded PEM as multi-line secret text instead."
fi
fi
fi
{
[ -n "$client_id" ] && echo "has_client_id=true" || echo "has_client_id=false"
[ -n "$app_id" ] && echo "has_app_id=true" || echo "has_app_id=false"
echo "client_id=$client_id"
echo "has_private_key=$has_private_key"
echo "private_key_valid=$private_key_valid"
} >> "$GITHUB_OUTPUT"
- uses: actions/create-github-app-token@v3
id: codeboarding-app-token-client
if: steps.codeboarding-app-config.outputs.has_client_id == 'true' && steps.codeboarding-app-config.outputs.private_key_valid == 'true'
continue-on-error: true
with:
client-id: ${{ steps.codeboarding-app-config.outputs.client_id }}
private-key: ${{ secrets.CODEBOARDING_APP_PRIVATE_KEY }}
- uses: actions/create-github-app-token@v3
id: codeboarding-app-token-app
if: steps.codeboarding-app-config.outputs.has_client_id != 'true' && steps.codeboarding-app-config.outputs.has_app_id == 'true' && steps.codeboarding-app-config.outputs.private_key_valid == 'true'
continue-on-error: true
with:
app-id: ${{ vars.CODEBOARDING_APP_ID }}
private-key: ${{ secrets.CODEBOARDING_APP_PRIVATE_KEY }}
- name: Warn when CodeBoarding App token is unavailable
if: steps.codeboarding-app-token-client.outputs.token == '' && steps.codeboarding-app-token-app.outputs.token == ''
shell: bash
run: |
echo "::warning::CodeBoarding GitHub App token is unavailable; the sync commit falls back to github-actions[bot]. Check CODEBOARDING_APP_PRIVATE_KEY formatting if app credentials are configured."
- uses: ./
with:
mode: sync
force_full: ${{ inputs.force_full || false }}
# App token authenticates the baseline push so the commit is attributed
# to the CodeBoarding App (logo avatar). Falls back to the workflow token,
# which can push because this job grants contents: write.
push_token: ${{ steps.codeboarding-app-token-client.outputs.token || steps.codeboarding-app-token-app.outputs.token || github.token }}
llm_api_key: ${{ secrets.OPENROUTER_API_KEY }}