Skip to content

Commit 8003bf3

Browse files
Orinksclaude
andcommitted
ci: inline WP push workflow, remove private reusable workflow dependency
Replace `uses: Orinks/orinks-github-releases/...@master` with a local push-releases.yml workflow and push_releases.py script. The private reusable workflow repo cannot be called from other private repos without making it public. This inlines the same logic so each repo is self-contained. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e0df637 commit 8003bf3

3 files changed

Lines changed: 159 additions & 1 deletion

File tree

.github/scripts/push_releases.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
"""Push GitHub release metadata to the WordPress site."""
2+
3+
from __future__ import annotations
4+
5+
import json
6+
import os
7+
import time
8+
import urllib.error
9+
import urllib.request
10+
from typing import Any
11+
12+
REPO = os.environ["REPO"]
13+
WP_URL = os.environ["WP_URL"].rstrip("/")
14+
WP_TOKEN = os.environ["WP_TOKEN"]
15+
BUST_CACHE_FIRST = os.environ.get("BUST_CACHE_FIRST", "false").lower() == "true"
16+
GH_TOKEN = os.environ.get("GITHUB_TOKEN")
17+
HEADERS = {
18+
"Content-Type": "application/json",
19+
"X-OGR-Token": WP_TOKEN,
20+
}
21+
GH_API_HEADERS: dict[str, str] = {
22+
"Accept": "application/vnd.github+json",
23+
}
24+
if GH_TOKEN:
25+
GH_API_HEADERS["Authorization"] = f"Bearer {GH_TOKEN}"
26+
27+
28+
def gh_json(endpoint: str, allow_missing: bool = False) -> Any:
29+
url = f"https://api.github.com/{endpoint}"
30+
request = urllib.request.Request(url, headers=GH_API_HEADERS)
31+
try:
32+
with urllib.request.urlopen(request, timeout=30) as response:
33+
return json.load(response)
34+
except urllib.error.HTTPError as exc:
35+
if allow_missing and exc.code == 404:
36+
return None
37+
raise
38+
39+
40+
def fetch_payload() -> dict[str, Any]:
41+
latest = gh_json(f"repos/{REPO}/releases/latest", allow_missing=True)
42+
all_releases = gh_json(f"repos/{REPO}/releases?per_page=20", allow_missing=True)
43+
if not isinstance(all_releases, list):
44+
all_releases = []
45+
return {
46+
"repo": REPO,
47+
"releases": all_releases[:20],
48+
"latest": latest if isinstance(latest, dict) and latest.get("tag_name") else None,
49+
}
50+
51+
52+
def push_releases(payload: dict[str, Any]) -> dict[str, Any]:
53+
"""Transmit release payload to the WordPress endpoint."""
54+
data = json.dumps(payload).encode()
55+
req = urllib.request.Request(
56+
f"{WP_URL}/wp-json/ogr/v1/push-releases",
57+
data=data,
58+
headers=HEADERS,
59+
method="POST",
60+
)
61+
with urllib.request.urlopen(req, timeout=30) as response:
62+
return json.load(response)
63+
64+
65+
def bust_cache() -> dict[str, Any]:
66+
"""Hit the optional bust-cache endpoint so the next push lands on fresh data."""
67+
req = urllib.request.Request(
68+
f"{WP_URL}/wp-json/ogr/v1/bust-cache",
69+
data=b"{}",
70+
headers=HEADERS,
71+
method="POST",
72+
)
73+
with urllib.request.urlopen(req, timeout=20) as response:
74+
return json.load(response)
75+
76+
77+
def main() -> None:
78+
payload = fetch_payload()
79+
80+
def attempt() -> dict[str, Any]:
81+
return push_releases(payload)
82+
83+
for attempt_num in range(2):
84+
try:
85+
result = attempt()
86+
print(f"Pushed {result['count']} releases for {result['repo']}")
87+
return
88+
except Exception:
89+
print(
90+
"First push attempt failed." if attempt_num == 0 else "Second push attempt failed."
91+
)
92+
if attempt_num == 0:
93+
if BUST_CACHE_FIRST:
94+
print("Cache nudge enabled. Hitting bust-cache before retry...")
95+
bust_result = bust_cache()
96+
print("Cache nudge response:", bust_result)
97+
print("Retrying once in 10s...")
98+
time.sleep(10)
99+
continue
100+
raise
101+
102+
103+
if __name__ == "__main__":
104+
main()
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Inline replacement for Orinks/orinks-github-releases reusable workflow.
2+
# That repo is private and cannot be referenced from other private repos
3+
# without making it public. This local workflow does the same thing.
4+
name: Push releases to WordPress
5+
6+
on:
7+
workflow_call:
8+
inputs:
9+
bust_cache_first:
10+
description: "Bust WordPress cache before retrying push"
11+
required: false
12+
default: false
13+
type: boolean
14+
secrets:
15+
WP_PUSH_TOKEN:
16+
required: true
17+
WP_SITE_URL:
18+
required: true
19+
workflow_dispatch:
20+
inputs:
21+
bust_cache_first:
22+
description: "Bust WordPress cache before retrying push"
23+
required: false
24+
default: false
25+
type: boolean
26+
27+
jobs:
28+
push:
29+
runs-on: ubuntu-latest
30+
timeout-minutes: 10
31+
steps:
32+
- name: Checkout repo
33+
uses: actions/checkout@v4
34+
- name: Push release data to WordPress
35+
env:
36+
WP_TOKEN: ${{ secrets.WP_PUSH_TOKEN }}
37+
WP_URL: ${{ secrets.WP_SITE_URL }}
38+
REPO: ${{ github.repository }}
39+
BUST_CACHE_FIRST: ${{ inputs.bust_cache_first || false }}
40+
run: |
41+
set -euo pipefail
42+
python3 .github/scripts/push_releases.py
Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
1+
# Triggers the local push-releases workflow instead of the private
2+
# Orinks/orinks-github-releases reusable workflow (which requires the
3+
# caller repo to be public or in the same org with visibility).
14
name: Update WordPress on release
25

36
on:
47
release:
58
types: [published]
9+
workflow_dispatch:
10+
inputs:
11+
bust_cache_first:
12+
description: "Bust WordPress cache before retrying push"
13+
required: false
14+
default: false
15+
type: boolean
616

717
jobs:
818
push-to-wordpress:
9-
uses: Orinks/orinks-github-releases/.github/workflows/push-releases.yml@master
19+
uses: ./.github/workflows/push-releases.yml
20+
with:
21+
bust_cache_first: ${{ inputs.bust_cache_first || false }}
1022
secrets:
1123
WP_PUSH_TOKEN: ${{ secrets.WP_PUSH_TOKEN }}
1224
WP_SITE_URL: ${{ secrets.WP_SITE_URL }}

0 commit comments

Comments
 (0)