Skip to content
Draft
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
73 changes: 3 additions & 70 deletions .github/workflows/update-version-dashboard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,75 +23,8 @@ jobs:
- name: Set up Nix
uses: cachix/install-nix-action@v31

- name: Update version dashboard
run: nix-shell --run 'npm run generate:version-compatibility-dashboard'

- name: Detect changes
id: changes
run: |
if [[ -n "$(git status --porcelain)" ]]; then
echo "has_changes=true" >> "$GITHUB_OUTPUT"
git status --short
git diff --stat
else
echo "has_changes=false" >> "$GITHUB_OUTPUT"
fi

- name: Check whitespace
if: steps.changes.outputs.has_changes == 'true'
run: git diff --check

- name: Create or update pull request
if: steps.changes.outputs.has_changes == 'true'
- name: Generate update pull requests
env:
GH_TOKEN: ${{ github.token }}
PR_BRANCH: version-dashboard/update
PR_TITLE: Update version dashboard data
run: |
set -euo pipefail

git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

git switch -c "$PR_BRANCH"
git add config/repo-version-config.json docs-main/snippets/generated/version-dashboard-data.mdx
git commit -m "$PR_TITLE"

if remote_sha="$(git ls-remote --heads origin "$PR_BRANCH" | awk '{print $1}')" && [[ -n "$remote_sha" ]]; then
git push --force-with-lease="refs/heads/$PR_BRANCH:$remote_sha" origin "HEAD:$PR_BRANCH"
else
git push origin "HEAD:$PR_BRANCH"
fi

pr_body="$(mktemp)"
cat > "$pr_body" <<'EOF'
Updates the committed Canton Network version dashboard data from public network, package, and installer sources.

Validation run by the workflow:
- `npm run generate:version-compatibility-dashboard`
- `git diff --check`
EOF

existing_pr_number="$(
gh pr list \
--repo "$GITHUB_REPOSITORY" \
--head "$PR_BRANCH" \
--base main \
--state open \
--json number \
--jq '.[0].number // empty'
)"

if [[ -n "$existing_pr_number" ]]; then
gh pr edit "$existing_pr_number" \
--repo "$GITHUB_REPOSITORY" \
--title "$PR_TITLE" \
--body-file "$pr_body"
else
gh pr create \
--base main \
--head "$PR_BRANCH" \
--repo "$GITHUB_REPOSITORY" \
--title "$PR_TITLE" \
--body-file "$pr_body"
fi
GITHUB_TOKEN: ${{ github.token }}
run: python3 scripts/update_generated_reference_prs.py --targets all
148 changes: 148 additions & 0 deletions scripts/generated_reference_pr_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
from __future__ import annotations

import subprocess
import tempfile
from pathlib import Path
from typing import Sequence


REPO_ROOT = Path(__file__).resolve().parents[1]


def run(command: Sequence[str], *, capture: bool = False) -> str:
kwargs: dict[str, object] = {
"cwd": REPO_ROOT,
"check": True,
"text": True,
}
if capture:
kwargs["stdout"] = subprocess.PIPE
completed = subprocess.run(list(command), **kwargs)
return completed.stdout.strip() if capture else ""


def git(*args: str, capture: bool = False) -> str:
return run(("git", *args), capture=capture)


def gh(*args: str, capture: bool = False) -> str:
return run(("gh", *args), capture=capture)


def current_repository() -> str:
return gh("repo", "view", "--json", "nameWithOwner", "--jq", ".nameWithOwner", capture=True)


def reset_to_base(*, base_sha: str, clean_paths: Sequence[str]) -> None:
git("switch", "--detach", base_sha)
git("reset", "--hard", base_sha)
git("clean", "-fd", "--", *clean_paths)


def write_base_file(base_sha: str, relative_path: str) -> Path:
before = tempfile.NamedTemporaryFile("w", encoding="utf-8", delete=False)
before_path = Path(before.name)
before.write(git("show", f"{base_sha}:{relative_path}", capture=True))
before.close()
return before_path


def has_changes(paths: Sequence[str]) -> bool:
output = git("status", "--porcelain", "--", *paths, capture=True)
return bool(output)


def push_branch(branch: str) -> None:
remote_output = git("ls-remote", "--heads", "origin", branch, capture=True)
remote_sha = remote_output.split()[0] if remote_output else ""
if remote_sha:
git(
"push",
f"--force-with-lease=refs/heads/{branch}:{remote_sha}",
"origin",
f"HEAD:{branch}",
)
else:
git("push", "origin", f"HEAD:{branch}")


def create_or_update_pull_request(
*,
title: str,
branch: str,
paths: Sequence[str],
body_path: Path,
base_branch: str,
repository: str,
) -> None:
if not has_changes(paths):
print(f"No changes for {title}")
return

git("status", "--short", "--", *paths)
git("switch", "-c", branch)
git("add", "--", *paths)
git("diff", "--cached", "--stat")
git("diff", "--cached", "--check")
git("commit", "-m", title)
push_branch(branch)

existing_pr_number = gh(
"pr",
"list",
"--repo",
repository,
"--head",
branch,
"--base",
base_branch,
"--state",
"open",
"--json",
"number",
"--jq",
".[0].number // empty",
capture=True,
)
if existing_pr_number:
gh(
"pr",
"edit",
existing_pr_number,
"--repo",
repository,
"--title",
title,
"--body-file",
str(body_path),
)
subprocess.run(
[
"gh",
"pr",
"ready",
existing_pr_number,
"--repo",
repository,
"--undo",
],
cwd=REPO_ROOT,
check=False,
)
return

gh(
"pr",
"create",
"--base",
base_branch,
"--head",
branch,
"--repo",
repository,
"--draft",
"--title",
title,
"--body-file",
str(body_path),
)
Loading