Skip to content

Commit adf9304

Browse files
[DOCS-15378] Add scheduled blog linker workflow (#39359)
* Add scheduled blog linker workflow and its write trust policy * Request review from jeff-morgan-dd on the weekly blog linker PR * Widen blog linker lookback to 14 days for run overlap
1 parent 8f289bb commit adf9304

2 files changed

Lines changed: 182 additions & 0 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
issuer: https://token.actions.githubusercontent.com
2+
3+
subject: "repo:DataDog/documentation:ref:refs/heads/master"
4+
5+
permissions:
6+
contents: write
7+
pull_requests: write
8+
9+
claim_pattern:
10+
repository: "DataDog/documentation"
11+
ref: "refs/heads/master"
12+
ref_type: "branch"
13+
event_name: "schedule|workflow_dispatch"
14+
job_workflow_ref: "DataDog/documentation/.github/workflows/blog_linker.yml@refs/heads/master"

.github/workflows/blog_linker.yml

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
name: Blog linker
2+
3+
# Adds Datadog blog post links to the further_reading section of the docs pages
4+
# each post references, then opens a draft PR with the result.
5+
#
6+
# The script itself lives in DataDog/websites-images
7+
# (services/webops-site-build/bin/docs-ci/blog_linker.py) and is fetched at run
8+
# time, so this workflow always uses the current version.
9+
10+
on:
11+
schedule:
12+
# Tuesdays at 12:00 UTC (08:00 ET)
13+
- cron: '0 12 * * 2'
14+
workflow_dispatch:
15+
inputs:
16+
since:
17+
description: 'Look back this many days for blog posts'
18+
required: false
19+
default: '14'
20+
dry_run:
21+
description: 'Report what would change without opening a PR'
22+
type: boolean
23+
required: false
24+
default: false
25+
26+
permissions:
27+
contents: read
28+
id-token: write
29+
30+
concurrency:
31+
group: blog-linker
32+
cancel-in-progress: false
33+
34+
jobs:
35+
link:
36+
runs-on: ubuntu-latest
37+
timeout-minutes: 20
38+
env:
39+
# Two weeks, against a weekly cron: every post falls in two runs, so a
40+
# dropped or failed run doesn't lose a week. The script skips posts
41+
# already linked, so the second pass is a no-op.
42+
SINCE: ${{ inputs.since || '14' }}
43+
steps:
44+
# Read access to websites-images, where the script lives.
45+
- name: Get token for websites-images
46+
id: sts-scripts
47+
uses: DataDog/dd-octo-sts-action@96a25462dbcb10ebf0bfd6e2ccc917d2ab235b9a # v1.0.4
48+
with:
49+
scope: DataDog/websites-images
50+
policy: documentation.blog-linker
51+
52+
# Write access to this repo, so the branch and PR are created by an
53+
# identity that triggers the normal PR checks (Vale and the rest).
54+
- name: Get token for documentation
55+
id: sts-docs
56+
uses: DataDog/dd-octo-sts-action@96a25462dbcb10ebf0bfd6e2ccc917d2ab235b9a # v1.0.4
57+
with:
58+
scope: DataDog/documentation
59+
policy: documentation.blog-linker-write
60+
61+
- name: Check out documentation
62+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
63+
with:
64+
token: ${{ steps.sts-docs.outputs.token }}
65+
66+
- name: Fetch the blog linker script
67+
env:
68+
GH_TOKEN: ${{ steps.sts-scripts.outputs.token }}
69+
run: |
70+
set -euo pipefail
71+
tmp=$(mktemp -d)
72+
git clone --depth 1 --filter=blob:none --sparse \
73+
"https://x-access-token:${GH_TOKEN}@github.com/DataDog/websites-images.git" "$tmp"
74+
git -C "$tmp" sparse-checkout set services/webops-site-build/bin/docs-ci
75+
cp "$tmp/services/webops-site-build/bin/docs-ci/blog_linker.py" ./blog_linker.py
76+
rm -rf "$tmp"
77+
78+
- name: Set up Python
79+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
80+
with:
81+
python-version: '3.12'
82+
83+
- name: Install dependencies
84+
run: pip install feedparser requests beautifulsoup4 ruamel.yaml
85+
86+
- name: Run the blog linker
87+
env:
88+
DRY_RUN: ${{ inputs.dry_run }}
89+
run: |
90+
set -euo pipefail
91+
args=(--since "$SINCE")
92+
if [ "$DRY_RUN" = "true" ]; then
93+
args+=(--dry-run)
94+
fi
95+
python ./blog_linker.py "${args[@]}" | tee summary.txt
96+
97+
# The script only writes to hugo/content/en. Scoping to that path keeps
98+
# the workflow's own files (blog_linker.py, summary.txt) out of the commit.
99+
- name: Check for changes
100+
id: changes
101+
run: |
102+
if git diff --quiet -- hugo/content/en; then
103+
echo "changed=false" >> "$GITHUB_OUTPUT"
104+
echo "No docs pages changed. Nothing to open a PR for."
105+
else
106+
echo "changed=true" >> "$GITHUB_OUTPUT"
107+
git diff --stat -- hugo/content/en
108+
fi
109+
110+
- name: Open a draft PR
111+
if: steps.changes.outputs.changed == 'true' && inputs.dry_run != true
112+
env:
113+
GH_TOKEN: ${{ steps.sts-docs.outputs.token }}
114+
run: |
115+
set -euo pipefail
116+
date_stamp=$(date -u +%Y-%m-%d)
117+
branch="blog-linker/weekly-${date_stamp}"
118+
119+
git config user.name "dd-octo-sts[bot]"
120+
git config user.email "200755185+dd-octo-sts[bot]@users.noreply.github.com"
121+
git checkout -b "$branch"
122+
# Same path scope as the check above: content changes only.
123+
git add -- hugo/content/en
124+
git commit -m "Add blog links to further_reading (week of ${date_stamp})"
125+
git push origin "$branch"
126+
127+
{
128+
echo '### What does this PR do? What is the motivation?'
129+
echo
130+
echo "Adds Datadog blog post links to the \`further_reading\` section of the docs pages"
131+
echo "those posts reference. Opened automatically by the [blog linker workflow][1];"
132+
echo "covers posts from the last ${SINCE} days."
133+
echo
134+
echo '<details><summary>Script output</summary>'
135+
echo
136+
echo '```'
137+
cat summary.txt
138+
echo '```'
139+
echo
140+
echo '</details>'
141+
echo
142+
echo '### Merge readiness'
143+
echo
144+
echo '- [ ] Ready for merge'
145+
echo
146+
echo '### Additional notes'
147+
echo
148+
echo 'Each entry pairs a blog post with a docs page that post links to.'
149+
echo
150+
echo "[1]: https://github.com/DataDog/documentation/blob/master/.github/workflows/blog_linker.yml"
151+
} > pr_body.md
152+
153+
gh pr create \
154+
--draft \
155+
--base master \
156+
--head "$branch" \
157+
--title "Add blog links to further_reading (week of ${date_stamp})" \
158+
--body-file pr_body.md \
159+
--label "WORK IN PROGRESS" \
160+
--reviewer jeff-morgan-dd
161+
162+
- name: Upload summary
163+
if: always()
164+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
165+
with:
166+
name: blog-linker-summary
167+
path: summary.txt
168+
if-no-files-found: ignore

0 commit comments

Comments
 (0)