Skip to content

Commit f599192

Browse files
authored
Automate article link map updates (#7)
* Automate article link map updates * Address PR existence check fooled by literal "null" string #7 (comment) * Address existing PR body becomes stale after force-push #7 (comment) * Address path-only changes misreported as both added and removed #7 (comment) * Clean up 1. Added Setup Node, Install dependencies steps — npm run update-article-link-map would have failed without Node and node_modules present. 2. Fixed the workflow link URL — now uses $GITHUB_SERVER_URL/$GITHUB_REPOSITORY env vars to build an absolute URL that resolves correctly from a PR page. Further clean up
1 parent 310f11f commit f599192

1 file changed

Lines changed: 145 additions & 0 deletions

File tree

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
name: Update Article Link Map
2+
3+
on:
4+
schedule:
5+
- cron: '0 9 * * 1,3,5'
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: write
10+
pull-requests: write
11+
12+
concurrency:
13+
group: update-article-link-map
14+
cancel-in-progress: false
15+
16+
jobs:
17+
update:
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: Checkout
21+
uses: actions/checkout@v4
22+
23+
- name: Setup Node
24+
uses: actions/setup-node@v4
25+
with:
26+
node-version-file: ".nvmrc"
27+
cache: "npm"
28+
29+
- name: Setup Python
30+
uses: actions/setup-python@v5
31+
with:
32+
python-version: "3.12"
33+
34+
- name: Install dependencies
35+
run: npm ci
36+
env:
37+
HUSKY: "0"
38+
39+
- name: Configure git credentials for private repo
40+
run: |
41+
git config --global url."https://${{ secrets.HELP_PAGES_CMS_TOKEN }}@dub.duckduckgo.com/".insteadOf "https://dub.duckduckgo.com/"
42+
43+
- name: Run update script
44+
run: npm run update-article-link-map
45+
46+
- name: Check for changes
47+
id: changes
48+
run: |
49+
if git diff --quiet src/config/zendesk.ts; then
50+
echo "changed=false" >> $GITHUB_OUTPUT
51+
else
52+
echo "changed=true" >> $GITHUB_OUTPUT
53+
fi
54+
55+
- name: Generate PR body
56+
if: steps.changes.outputs.changed == 'true'
57+
run: |
58+
python3 - << 'EOF'
59+
import os
60+
import re
61+
import subprocess
62+
63+
diff = subprocess.run(
64+
['git', 'diff', 'src/config/zendesk.ts'],
65+
capture_output=True, text=True
66+
).stdout
67+
68+
added, removed = set(), set()
69+
for line in diff.splitlines():
70+
if line.startswith('+') and not line.startswith('+++'):
71+
m = re.search(r"'(\d+)':", line)
72+
if m:
73+
added.add(m.group(1))
74+
elif line.startswith('-') and not line.startswith('---'):
75+
m = re.search(r"'(\d+)':", line)
76+
if m:
77+
removed.add(m.group(1))
78+
79+
# IDs in both sets had their path changed, not added or removed
80+
updated = added & removed
81+
added -= updated
82+
removed -= updated
83+
84+
lines = [
85+
"## Summary\n\n",
86+
"Automated update of `ARTICLE_LINK_MAP` in `src/config/zendesk.ts` "
87+
"from [`help-pages-cms`](https://dub.duckduckgo.com/duckduckgo/help-pages-cms).\n\n",
88+
"### Changes\n\n",
89+
]
90+
91+
if added:
92+
ids = ", ".join(f"`{i}`" for i in sorted(added))
93+
lines.append(f"**Added ({len(added)}):** {ids}\n\n")
94+
if removed:
95+
ids = ", ".join(f"`{i}`" for i in sorted(removed))
96+
lines.append(f"**Removed ({len(removed)}):** {ids}\n\n")
97+
if updated:
98+
ids = ", ".join(f"`{i}`" for i in sorted(updated))
99+
lines.append(f"**Path updated ({len(updated)}):** {ids}\n\n")
100+
if not added and not removed and not updated:
101+
lines.append("No article ID or path changes detected.\n\n")
102+
103+
lines += [
104+
"### Checklist\n\n",
105+
"- [ ] Review the diff for unexpected changes\n",
106+
"- [ ] Confirm `npm run build` passes\n\n",
107+
"---\n",
108+
f"🤖 Generated by the "
109+
f"[update-article-link-map]({os.environ['GITHUB_SERVER_URL']}/{os.environ['GITHUB_REPOSITORY']}/actions/workflows/update-article-link-map.yml) workflow.",
110+
]
111+
112+
with open('/tmp/pr-body.md', 'w') as f:
113+
f.writelines(lines)
114+
EOF
115+
116+
- name: Commit and push branch
117+
if: steps.changes.outputs.changed == 'true'
118+
run: |
119+
git config user.name "github-actions[bot]"
120+
git config user.email "github-actions[bot]@users.noreply.github.com"
121+
git checkout -B automated/update-article-link-map
122+
git add src/config/zendesk.ts
123+
git commit -m "chore: update ARTICLE_LINK_MAP from help-pages-cms"
124+
git push origin automated/update-article-link-map --force
125+
126+
- name: Create PR if one does not exist
127+
if: steps.changes.outputs.changed == 'true'
128+
env:
129+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
130+
run: |
131+
EXISTING=$(gh pr list --head automated/update-article-link-map --json url --jq '.[0].url // empty')
132+
if [ -n "$EXISTING" ]; then
133+
echo "PR already exists at $EXISTING — updating body"
134+
gh pr edit "$EXISTING" --body-file /tmp/pr-body.md
135+
else
136+
gh pr create \
137+
--title "chore: update ARTICLE_LINK_MAP from help-pages-cms" \
138+
--body-file /tmp/pr-body.md \
139+
--base main \
140+
--head automated/update-article-link-map
141+
fi
142+
143+
- name: No changes detected
144+
if: steps.changes.outputs.changed == 'false'
145+
run: echo "ARTICLE_LINK_MAP is already up to date — no PR needed"

0 commit comments

Comments
 (0)