Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions .github/scripts/push_releases.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
"""Push GitHub release metadata to the WordPress site."""

from __future__ import annotations

import json
import os
import time
import urllib.error
import urllib.request
from typing import Any

REPO = os.environ["REPO"]
WP_URL = os.environ["WP_URL"].rstrip("/")
WP_TOKEN = os.environ["WP_TOKEN"]
BUST_CACHE_FIRST = os.environ.get("BUST_CACHE_FIRST", "false").lower() == "true"
GH_TOKEN = os.environ.get("GITHUB_TOKEN")
HEADERS = {
"Content-Type": "application/json",
"X-OGR-Token": WP_TOKEN,
}
GH_API_HEADERS: dict[str, str] = {
"Accept": "application/vnd.github+json",
}
if GH_TOKEN:
GH_API_HEADERS["Authorization"] = f"Bearer {GH_TOKEN}"


def gh_json(endpoint: str, allow_missing: bool = False) -> Any:
url = f"https://api.github.com/{endpoint}"
request = urllib.request.Request(url, headers=GH_API_HEADERS)
try:
with urllib.request.urlopen(request, timeout=30) as response:
return json.load(response)
except urllib.error.HTTPError as exc:
if allow_missing and exc.code == 404:
return None
raise


def fetch_payload() -> dict[str, Any]:
latest = gh_json(f"repos/{REPO}/releases/latest", allow_missing=True)
all_releases = gh_json(f"repos/{REPO}/releases?per_page=20", allow_missing=True)
if not isinstance(all_releases, list):
all_releases = []
return {
"repo": REPO,
"releases": all_releases[:20],
"latest": latest if isinstance(latest, dict) and latest.get("tag_name") else None,
}


def push_releases(payload: dict[str, Any]) -> dict[str, Any]:
"""Transmit release payload to the WordPress endpoint."""
data = json.dumps(payload).encode()
req = urllib.request.Request(
f"{WP_URL}/wp-json/ogr/v1/push-releases",
data=data,
headers=HEADERS,
method="POST",
)
with urllib.request.urlopen(req, timeout=30) as response:
return json.load(response)


def bust_cache() -> dict[str, Any]:
"""Hit the optional bust-cache endpoint so the next push lands on fresh data."""
req = urllib.request.Request(
f"{WP_URL}/wp-json/ogr/v1/bust-cache",
data=b"{}",
headers=HEADERS,
method="POST",
)
with urllib.request.urlopen(req, timeout=20) as response:
return json.load(response)


def main() -> None:
payload = fetch_payload()

def attempt() -> dict[str, Any]:
return push_releases(payload)

for attempt_num in range(2):
try:
result = attempt()
print(f"Pushed {result['count']} releases for {result['repo']}")
return
except Exception as exc:
print("First push attempt failed." if attempt_num == 0 else "Second push attempt failed.")
if attempt_num == 0:
if BUST_CACHE_FIRST:
print("Cache nudge enabled. Hitting bust-cache before retry...")
bust_result = bust_cache()
print("Cache nudge response:", bust_result)
print("Retrying once in 10s...")
time.sleep(10)
continue
raise


if __name__ == "__main__":
main()
6 changes: 4 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,10 @@ jobs:

push-to-wordpress:
needs: release
if: ${{ github.event_name != 'workflow_dispatch' || inputs.dry_run != true }}
uses: Orinks/orinks-github-releases/.github/workflows/push-releases.yml@master
if: ${{ needs.release.result == 'success' }}
uses: ./.github/workflows/push-releases.yml
with:
bust_cache_first: false
secrets:
WP_PUSH_TOKEN: ${{ secrets.WP_PUSH_TOKEN }}
WP_SITE_URL: ${{ secrets.WP_SITE_URL }}
39 changes: 39 additions & 0 deletions .github/workflows/push-releases.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Push releases to WordPress

on:
workflow_call:
inputs:
bust_cache_first:
description: "Bust WordPress cache before retrying push"
required: false
default: false
type: boolean
secrets:
WP_PUSH_TOKEN:
required: true
WP_SITE_URL:
required: true
workflow_dispatch:
inputs:
bust_cache_first:
description: "Bust WordPress cache before retrying push"
required: false
default: false
type: boolean

jobs:
push:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Validate required secrets
env:
WP_TOKEN: ${{ secrets.WP_PUSH_TOKEN }}
WP_URL: ${{ secrets.WP_SITE_URL }}
REPO: ${{ github.repository }}
BUST_CACHE_FIRST: ${{ inputs.bust_cache_first || false }}
run: |
set -euo pipefail
python3 .github/scripts/push_releases.py
11 changes: 10 additions & 1 deletion .github/workflows/update-wordpress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,19 @@ name: Update WordPress on release
on:
release:
types: [published]
workflow_dispatch:
inputs:
bust_cache_first:
description: "Bust WordPress cache before retrying push"
required: false
default: false
type: boolean

jobs:
push-to-wordpress:
uses: Orinks/orinks-github-releases/.github/workflows/push-releases.yml@master
uses: ./.github/workflows/push-releases.yml
with:
bust_cache_first: ${{ inputs.bust_cache_first || false }}
secrets:
WP_PUSH_TOKEN: ${{ secrets.WP_PUSH_TOKEN }}
WP_SITE_URL: ${{ secrets.WP_SITE_URL }}