Skip to content

Commit 92bdc27

Browse files
authored
Harden workflow credentials (koxudaxi#3095)
* Harden auto-fix workflows * Harden release workflows * Harden workflow credentials * Fix docs preview comment permissions * Refactor workflow autofix and docs sync * Add test workflow gate * Harden generated docs sync push * Harden workflow ownership and pins * Split release draft privileges * Harden release draft workflow
1 parent e91b601 commit 92bdc27

20 files changed

Lines changed: 560 additions & 382 deletions

.github/CODEOWNERS

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Protect automation that can affect CI/CD behavior or main-only trusted jobs.
2+
/.github/workflows/** @koxudaxi
3+
/.github/CODEOWNERS @koxudaxi
4+
/.pre-commit-config.yaml @koxudaxi
5+
/tox.ini @koxudaxi
6+
/zensical.toml @koxudaxi
7+
/scripts/update_command_help_on_markdown.py @koxudaxi
8+
/scripts/build_cli_docs.py @koxudaxi
9+
/scripts/build_prompt_data.py @koxudaxi
10+
/scripts/build_schema_docs.py @koxudaxi
11+
/scripts/build_llms_txt.py @koxudaxi
12+
/scripts/update_docs_version.py @koxudaxi

.github/dependabot.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,15 @@ updates:
1010
allow:
1111
- dependency-type: direct
1212
- dependency-type: indirect
13+
- package-ecosystem: github-actions
14+
directory: "/"
15+
schedule:
16+
interval: weekly
17+
day: thursday
18+
time: "10:30"
19+
timezone: Asia/Tokyo
20+
open-pull-requests-limit: 10
21+
groups:
22+
github-actions:
23+
patterns:
24+
- "*"

.github/workflows/changelog.yaml

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@ on:
55
types: [published]
66

77
jobs:
8-
update-changelog:
8+
build-changelog:
99
runs-on: ubuntu-latest
1010
permissions:
11-
contents: write
11+
contents: read
12+
outputs:
13+
has_changes: ${{ steps.patch.outputs.has_changes }}
1214
steps:
13-
- uses: actions/checkout@v4
15+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
1416
with:
1517
ref: main
16-
token: ${{ secrets.PAT }}
18+
persist-credentials: false
1719

1820
- name: Get release info and update CHANGELOG
1921
env:
@@ -60,10 +62,56 @@ jobs:
6062
cat header.md new_entry.md old_entries.md > CHANGELOG.md
6163
rm -f header.md new_entry.md old_entries.md
6264
65+
- name: Create changelog patch
66+
id: patch
67+
env:
68+
PATCH_PATH: ${{ runner.temp }}/changelog.patch
69+
run: |
70+
set -euo pipefail
71+
if git diff --quiet -- CHANGELOG.md; then
72+
echo "has_changes=false" >> "$GITHUB_OUTPUT"
73+
exit 0
74+
fi
75+
git diff --binary -- CHANGELOG.md > "$PATCH_PATH"
76+
echo "has_changes=true" >> "$GITHUB_OUTPUT"
77+
- name: Upload changelog patch
78+
if: steps.patch.outputs.has_changes == 'true'
79+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
80+
with:
81+
name: changelog-patch
82+
path: ${{ runner.temp }}/changelog.patch
83+
if-no-files-found: error
84+
85+
commit-changelog:
86+
needs: build-changelog
87+
if: needs.build-changelog.outputs.has_changes == 'true'
88+
runs-on: ubuntu-latest
89+
permissions:
90+
contents: write
91+
steps:
92+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
93+
with:
94+
ref: main
95+
fetch-depth: 0
96+
persist-credentials: false
97+
- name: Download changelog patch
98+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
99+
with:
100+
name: changelog-patch
101+
path: ${{ runner.temp }}
63102
- name: Commit and push
103+
env:
104+
GH_TOKEN: ${{ github.token }}
105+
PATCH_PATH: ${{ runner.temp }}/changelog.patch
64106
run: |
107+
set -euo pipefail
108+
git apply --index --whitespace=nowarn "$PATCH_PATH"
109+
if git diff --staged --quiet; then
110+
exit 0
111+
fi
65112
git config user.name "github-actions[bot]"
66113
git config user.email "github-actions[bot]@users.noreply.github.com"
67-
git add CHANGELOG.md
68-
git diff --cached --quiet || git commit -m "docs: update CHANGELOG.md for ${{ github.event.release.tag_name }}"
69-
git push
114+
git commit -m "docs: update CHANGELOG.md for ${{ github.event.release.tag_name }}"
115+
git fetch origin main
116+
git rebase origin/main
117+
git push "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git" HEAD:main

.github/workflows/cli-docs.yaml

Lines changed: 7 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
11
name: Update CLI Docs
22

33
on:
4-
push:
5-
branches: [main]
6-
paths:
7-
- 'tests/main/**'
8-
- 'tests/test_main_kr.py'
9-
- 'src/datamodel_code_generator/arguments.py'
10-
- 'src/datamodel_code_generator/cli_options.py'
11-
- 'scripts/build_cli_docs.py'
12-
- 'scripts/build_prompt_data.py'
134
pull_request:
145
branches: [main]
156
paths:
@@ -19,50 +10,24 @@ on:
1910
- 'src/datamodel_code_generator/cli_options.py'
2011
- 'scripts/build_cli_docs.py'
2112
- 'scripts/build_prompt_data.py'
22-
pull_request_target:
23-
types: [labeled]
24-
paths:
25-
- 'tests/main/**'
26-
- 'tests/test_main_kr.py'
27-
- 'src/datamodel_code_generator/arguments.py'
28-
- 'src/datamodel_code_generator/cli_options.py'
29-
- 'scripts/build_cli_docs.py'
30-
- 'scripts/build_prompt_data.py'
13+
- 'docs/cli-reference/**'
14+
- 'src/datamodel_code_generator/prompt_data.py'
3115

3216
permissions:
33-
contents: write
17+
contents: read
3418

3519
jobs:
3620
update-cli-docs:
37-
if: |
38-
github.event_name == 'push' ||
39-
!github.event.pull_request.head.repo.fork ||
40-
github.actor == 'koxudaxi' ||
41-
github.actor == 'gaborbernat' ||
42-
github.actor == 'ilovelinux' ||
43-
(github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-fix' &&
44-
(github.event.sender.login == 'koxudaxi' ||
45-
github.event.sender.login == 'gaborbernat' ||
46-
github.event.sender.login == 'ilovelinux'))
4721
runs-on: ubuntu-latest
4822
steps:
49-
# Checkout for forks (no PAT available)
50-
- uses: actions/checkout@v4
51-
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository
23+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
5224
with:
5325
fetch-depth: 0
54-
ref: ${{ github.event.pull_request.head.ref }}
26+
ref: ${{ github.event.pull_request.head.sha }}
5527
repository: ${{ github.event.pull_request.head.repo.full_name }}
56-
# Checkout for same-repo PRs, pushes, and pull_request_target
57-
- uses: actions/checkout@v4
58-
if: github.event_name == 'push' || github.event_name == 'pull_request_target' || github.event.pull_request.head.repo.full_name == github.repository
59-
with:
60-
fetch-depth: 0
61-
ref: ${{ github.event.pull_request.head.ref || github.ref }}
62-
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
63-
token: ${{ secrets.PAT }}
28+
persist-credentials: false
6429
- name: Install the latest version of uv
65-
uses: astral-sh/setup-uv@v5
30+
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5
6631
- name: Install tox
6732
run: uv tool install --python-preference only-managed --python 3.13 tox --with tox-uv
6833
- name: Setup environment
@@ -75,13 +40,3 @@ jobs:
7540
run: .tox/cli-docs/bin/python scripts/build_cli_docs.py
7641
- name: Build prompt data
7742
run: .tox/cli-docs/bin/python scripts/build_prompt_data.py
78-
- name: Commit and push if changed
79-
if: github.event_name == 'push' || github.event_name == 'pull_request_target' || github.event.pull_request.head.repo.full_name == github.repository
80-
run: |
81-
git config user.name "github-actions[bot]"
82-
git config user.email "github-actions[bot]@users.noreply.github.com"
83-
git add docs/cli-reference/ src/datamodel_code_generator/prompt_data.py
84-
git diff --staged --quiet || git commit -m "docs: update CLI reference documentation and prompt data
85-
86-
🤖 Generated by GitHub Actions"
87-
git push

.github/workflows/codeql.yaml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,20 @@ jobs:
2929

3030
steps:
3131
- name: Checkout
32-
uses: actions/checkout@v4
32+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
33+
with:
34+
persist-credentials: false
3335

3436
- name: Initialize CodeQL
35-
uses: github/codeql-action/init@v2
37+
uses: github/codeql-action/init@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a # v3
3638
with:
3739
languages: ${{ matrix.language }}
3840
queries: +security-and-quality
3941

4042
- name: Autobuild
41-
uses: github/codeql-action/autobuild@v2
43+
uses: github/codeql-action/autobuild@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a # v3
4244

4345
- name: Perform CodeQL Analysis
44-
uses: github/codeql-action/analyze@v2
46+
uses: github/codeql-action/analyze@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a # v3
4547
with:
4648
category: "/language:${{ matrix.language }}"

.github/workflows/codespell.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ jobs:
2222

2323
steps:
2424
- name: Checkout
25-
uses: actions/checkout@v4
25+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
26+
with:
27+
persist-credentials: false
2628
- name: Codespell
27-
uses: codespell-project/actions-codespell@v2
29+
uses: codespell-project/actions-codespell@406322ec52dd7b488e48c1c4b82e2a8b3a1bf630 # v2
2830
with:
2931
exclude_file: CODE_OF_CONDUCT.md
3032
skip: ./docs/cli-reference,./docs/llms.txt,./docs/llms-full.txt

.github/workflows/codspeed.yaml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,27 @@ concurrency:
1313
group: codespeed-${{ github.ref }}
1414
cancel-in-progress: true
1515

16+
permissions:
17+
contents: read
18+
1619
jobs:
1720
benchmarks:
1821
runs-on: ubuntu-24.04
1922
steps:
20-
- uses: actions/checkout@v4
23+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
24+
with:
25+
persist-credentials: false
2126
# uv standalone build is not compatible with CodSpeedHQ
2227
# https://github.com/astral-sh/uv/issues/11006
23-
- uses: actions/setup-python@v6
28+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
2429
with:
2530
python-version: "3.14.2"
2631
- name: Install the latest version of uv
27-
uses: astral-sh/setup-uv@v5
32+
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5
2833
- name: Install dependencies
2934
run: uv sync --all-extras --group benchmark
3035
- name: Run benchmarks
31-
uses: CodSpeedHQ/action@v4
36+
uses: CodSpeedHQ/action@db35df748deb45fdef0960669f57d627c1956c30 # v4
3237
with:
3338
token: ${{ secrets.CODSPEED_TOKEN }}
3439
run: .venv/bin/pytest tests/main/test_performance.py --codspeed

.github/workflows/config-types.yaml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,18 @@ on:
1414
- 'pyproject.toml'
1515
- '.github/workflows/config-types.yaml'
1616

17+
permissions:
18+
contents: read
19+
1720
jobs:
1821
config-types:
1922
runs-on: ubuntu-latest
2023
steps:
21-
- uses: actions/checkout@v4
24+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
25+
with:
26+
persist-credentials: false
2227

23-
- uses: astral-sh/setup-uv@v5
28+
- uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5
2429
with:
2530
enable-cache: true
2631

.github/workflows/docs-deploy.yaml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Docs Deploy
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
checkout_ref:
7+
required: true
8+
type: string
9+
deploy_branch:
10+
required: false
11+
type: string
12+
default: ''
13+
secrets:
14+
CLOUDFLARE_API_TOKEN:
15+
required: false
16+
CLOUDFLARE_ACCOUNT_ID:
17+
required: false
18+
19+
jobs:
20+
build-deploy:
21+
runs-on: ubuntu-24.04
22+
concurrency:
23+
group: docs-deploy-${{ inputs.deploy_branch || inputs.checkout_ref }}
24+
cancel-in-progress: true
25+
permissions:
26+
contents: read
27+
steps:
28+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
29+
with:
30+
ref: ${{ inputs.checkout_ref }}
31+
persist-credentials: false
32+
- name: Install the latest version of uv
33+
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5
34+
with:
35+
python-version: 3.13
36+
- name: Install dependencies
37+
run: uv sync
38+
- name: Copy CHANGELOG to docs
39+
run: |
40+
if [ -f CHANGELOG.md ]; then
41+
cp CHANGELOG.md docs/changelog.md
42+
else
43+
echo "# Changelog" > docs/changelog.md
44+
echo "" >> docs/changelog.md
45+
echo "Changelog will be available after the first release." >> docs/changelog.md
46+
fi
47+
- name: Update GitHub Action version in docs
48+
run: python scripts/update_docs_version.py
49+
env:
50+
GH_TOKEN: ${{ github.token }}
51+
- name: Build site
52+
run: zensical build --clean
53+
- name: Deploy
54+
if: inputs.deploy_branch != ''
55+
env:
56+
DEPLOY_BRANCH: ${{ inputs.deploy_branch }}
57+
uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3
58+
with:
59+
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
60+
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
61+
command: pages deploy site --project-name=datamodel-code-generator --branch="$DEPLOY_BRANCH"

0 commit comments

Comments
 (0)