Skip to content

Update Article Link Map #3

Update Article Link Map

Update Article Link Map #3

name: Update Article Link Map
on:
schedule:
- cron: '0 9 * * 1,3,5'
workflow_dispatch:
permissions:
contents: write
pull-requests: write
concurrency:
group: update-article-link-map
cancel-in-progress: false
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
update:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
cache: "npm"
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: npm ci
env:
HUSKY: "0"
- name: Configure git credentials for private repo
run: |
git config --global url."https://${{ secrets.HELP_PAGES_CMS_TOKEN }}@dub.duckduckgo.com/".insteadOf "https://dub.duckduckgo.com/"
- name: Run update script
run: npm run update-article-link-map
- name: Check for changes
id: changes
run: |
if git diff --quiet src/config/zendesk.ts; then
echo "changed=false" >> $GITHUB_OUTPUT
else
echo "changed=true" >> $GITHUB_OUTPUT
fi
- name: Generate PR body
if: steps.changes.outputs.changed == 'true'
run: |
python3 - << 'EOF'
import os
import re
import subprocess
diff = subprocess.run(
['git', 'diff', 'src/config/zendesk.ts'],
capture_output=True, text=True
).stdout
added, removed = set(), set()
for line in diff.splitlines():
if line.startswith('+') and not line.startswith('+++'):
m = re.search(r"'(\d+)':", line)
if m:
added.add(m.group(1))
elif line.startswith('-') and not line.startswith('---'):
m = re.search(r"'(\d+)':", line)
if m:
removed.add(m.group(1))
# IDs in both sets had their path changed, not added or removed
updated = added & removed
added -= updated
removed -= updated
lines = [
"## Summary\n\n",
"Automated update of `ARTICLE_LINK_MAP` in `src/config/zendesk.ts` "
"from [`help-pages-cms`](https://dub.duckduckgo.com/duckduckgo/help-pages-cms).\n\n",
"### Changes\n\n",
]
if added:
ids = ", ".join(f"`{i}`" for i in sorted(added))
lines.append(f"**Added ({len(added)}):** {ids}\n\n")
if removed:
ids = ", ".join(f"`{i}`" for i in sorted(removed))
lines.append(f"**Removed ({len(removed)}):** {ids}\n\n")
if updated:
ids = ", ".join(f"`{i}`" for i in sorted(updated))
lines.append(f"**Path updated ({len(updated)}):** {ids}\n\n")
if not added and not removed and not updated:
lines.append("No article ID or path changes detected.\n\n")
lines += [
"### Checklist\n\n",
"- [ ] Review the diff for unexpected changes\n",
"- [ ] Confirm `npm run build` passes\n\n",
"---\n",
f"🤖 Generated by the "
f"[update-article-link-map]({os.environ['GITHUB_SERVER_URL']}/{os.environ['GITHUB_REPOSITORY']}/actions/workflows/update-article-link-map.yml) workflow.",
]
with open('/tmp/pr-body.md', 'w') as f:
f.writelines(lines)
EOF
- name: Commit and push branch
if: steps.changes.outputs.changed == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git checkout -B automated/update-article-link-map
git add src/config/zendesk.ts
git commit -m "chore: update ARTICLE_LINK_MAP from help-pages-cms"
git push origin automated/update-article-link-map --force
- name: Create PR if one does not exist
if: steps.changes.outputs.changed == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
EXISTING=$(gh pr list --head automated/update-article-link-map --json url --jq '.[0].url // empty')
if [ -n "$EXISTING" ]; then
echo "PR already exists at $EXISTING — updating body"
gh pr edit "$EXISTING" --body-file /tmp/pr-body.md
else
gh pr create \
--title "chore: update ARTICLE_LINK_MAP from help-pages-cms" \
--body-file /tmp/pr-body.md \
--base main \
--head automated/update-article-link-map
fi
- name: No changes detected
if: steps.changes.outputs.changed == 'false'
run: echo "ARTICLE_LINK_MAP is already up to date — no PR needed"