lawallet-nwc-release #6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Update LaWallet NWC | |
| on: | |
| repository_dispatch: | |
| types: [lawallet-nwc-release] | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "LaWallet NWC version to package, with or without a leading v" | |
| required: true | |
| type: string | |
| image: | |
| description: "Full Docker image tag. Defaults to masize/lawallet-nwc:<version>." | |
| required: false | |
| type: string | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: update-lawallet-nwc-${{ github.event.client_payload.version || inputs.version || github.run_id }} | |
| cancel-in-progress: false | |
| jobs: | |
| update: | |
| name: Update Umbrel package | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: master | |
| persist-credentials: false | |
| - name: Resolve package inputs | |
| id: package | |
| env: | |
| DISPATCH_VERSION: ${{ github.event.client_payload.version }} | |
| DISPATCH_IMAGE: ${{ github.event.client_payload.image }} | |
| INPUT_VERSION: ${{ inputs.version }} | |
| INPUT_IMAGE: ${{ inputs.image }} | |
| run: | | |
| set -euo pipefail | |
| VERSION="${DISPATCH_VERSION:-${INPUT_VERSION:-}}" | |
| VERSION="${VERSION#v}" | |
| if [ -z "${VERSION}" ]; then | |
| echo "::error::Missing LaWallet NWC version." | |
| exit 1 | |
| fi | |
| IMAGE="${DISPATCH_IMAGE:-${INPUT_IMAGE:-}}" | |
| if [ -z "${IMAGE}" ]; then | |
| IMAGE="masize/lawallet-nwc:${VERSION}" | |
| fi | |
| BRANCH_VERSION="$(printf "%s" "${VERSION}" | tr -cd "0-9A-Za-z._-")" | |
| { | |
| echo "version=${VERSION}" | |
| echo "image=${IMAGE}" | |
| echo "branch=automation/lawallet-nwc-${BRANCH_VERSION}" | |
| } >> "${GITHUB_OUTPUT}" | |
| - name: Update package files | |
| env: | |
| VERSION: ${{ steps.package.outputs.version }} | |
| IMAGE: ${{ steps.package.outputs.image }} | |
| SOURCE_REPOSITORY: ${{ github.event.client_payload.source_repository }} | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| set -euo pipefail | |
| SRC_REPO="${SOURCE_REPOSITORY:-lawalletio/lawallet-nwc}" | |
| # Best-effort fetch of the published GitHub Release notes for this | |
| # version. If the release (or token) is unavailable, RELEASE_BODY stays | |
| # empty and the package falls back to a versioned pointer note. | |
| RELEASE_BODY="$(gh release view "v${VERSION}" --repo "${SRC_REPO}" --json body --jq '.body' 2>/dev/null || true)" | |
| export SRC_REPO RELEASE_BODY | |
| python3 <<'PY' | |
| import os | |
| import re | |
| from pathlib import Path | |
| version = os.environ["VERSION"] | |
| image = os.environ["IMAGE"] | |
| src_repo = os.environ.get("SRC_REPO") or "lawalletio/lawallet-nwc" | |
| release_body = os.environ.get("RELEASE_BODY", "") or "" | |
| def replace_once(path, pattern, replacement): | |
| file_path = Path(path) | |
| original = file_path.read_text() | |
| updated, count = re.subn(pattern, replacement, original, count=1, flags=re.MULTILINE) | |
| if count != 1: | |
| raise SystemExit(f"Expected exactly one match in {path}, found {count}") | |
| file_path.write_text(updated) | |
| replace_once( | |
| "lawallet-nwc/umbrel-app.yml", | |
| r"^version:\s*.*$", | |
| lambda match: f'version: "{version}"', | |
| ) | |
| for compose_file in ("lawallet-nwc/docker-compose.yml", "test/docker-compose.regtest.yml"): | |
| replace_once( | |
| compose_file, | |
| r"^(\s+image:\s+)masize/lawallet-nwc:[^\s]+$", | |
| lambda match: f"{match.group(1)}{image}", | |
| ) | |
| replace_once( | |
| "README.md", | |
| r"^(- Published image: `)masize/lawallet-nwc:[^`]+(`)$", | |
| lambda match: f"{match.group(1)}{image}{match.group(2)}", | |
| ) | |
| # Keep the Umbrel "update available" note in sync with the release. | |
| # Distill the GitHub Release body into a concise note, falling back to | |
| # a versioned pointer when the body is empty or just the changelog stub. | |
| release_url = f"https://github.com/{src_repo}/releases/tag/v{version}" | |
| text = re.sub(r"<!--.*?-->", "", release_body, flags=re.DOTALL) | |
| kept = [] | |
| for line in text.splitlines(): | |
| stripped = line.strip() | |
| if re.match(r"^#\s*v?\d", stripped): # "# v1.2.3" title | |
| continue | |
| if re.match(r"^##\s+release date\b", stripped, re.I): | |
| continue | |
| if re.match(r"^\d{4}-\d{2}-\d{2}$", stripped): # bare date line | |
| continue | |
| kept.append(line.rstrip()) | |
| cleaned = re.sub(r"\n{3,}", "\n\n", "\n".join(kept)).strip() | |
| is_stub = (not cleaned) or ("no merged prs" in cleaned.lower()) | |
| if is_stub: | |
| note = f"LaWallet NWC {version}." | |
| else: | |
| limit = 1500 | |
| if len(cleaned) > limit: | |
| cleaned = cleaned[:limit].rstrip() + "…" | |
| note = cleaned | |
| note = f"{note}\n\nFull release notes: {release_url}" | |
| # Literal block scalar (|-) preserves line breaks; every line is | |
| # indented two spaces so arbitrary markdown can't break out of the | |
| # YAML block. Replaces the whole releaseNotes block (key line through | |
| # the line before the next top-level key, or EOF). | |
| block = "releaseNotes: |-\n" + "\n".join( | |
| ((" " + ln).rstrip() if ln else "") for ln in note.splitlines() | |
| ) + "\n" | |
| notes_path = Path("lawallet-nwc/umbrel-app.yml") | |
| content = notes_path.read_text() | |
| content, count = re.subn( | |
| r"^releaseNotes:.*?(?=^\S|\Z)", | |
| lambda _match: block, | |
| content, | |
| count=1, | |
| flags=re.DOTALL | re.MULTILINE, | |
| ) | |
| if count != 1: | |
| raise SystemExit(f"Expected exactly one releaseNotes block, found {count}") | |
| notes_path.write_text(content) | |
| PY | |
| grep -n 'version:' lawallet-nwc/umbrel-app.yml | |
| grep -RIn 'image: masize/lawallet-nwc:' lawallet-nwc/docker-compose.yml test/docker-compose.regtest.yml | |
| grep -n 'Published image:' README.md | |
| echo '--- releaseNotes ---' | |
| sed -n '/^releaseNotes:/,$p' lawallet-nwc/umbrel-app.yml | |
| - name: Open and merge package update pull request | |
| env: | |
| GH_TOKEN: ${{ secrets.UMBREL_APP_STORE_UPDATE_TOKEN }} | |
| VERSION: ${{ steps.package.outputs.version }} | |
| IMAGE: ${{ steps.package.outputs.image }} | |
| BRANCH: ${{ steps.package.outputs.branch }} | |
| SOURCE_REPOSITORY: ${{ github.event.client_payload.source_repository }} | |
| SOURCE_RUN_URL: ${{ github.event.client_payload.source_run_url }} | |
| run: | | |
| set -euo pipefail | |
| if [ -z "${GH_TOKEN}" ]; then | |
| echo "::error::Missing UMBREL_APP_STORE_UPDATE_TOKEN. Configure a token with contents and pull request write access to lawalletio/umbrel-app-store." | |
| exit 1 | |
| fi | |
| if git diff --quiet; then | |
| echo "LaWallet NWC package is already up to date." | |
| exit 0 | |
| fi | |
| git diff --check | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" | |
| git checkout -B "${BRANCH}" | |
| git add README.md lawallet-nwc/umbrel-app.yml lawallet-nwc/docker-compose.yml test/docker-compose.regtest.yml | |
| git commit -m "Update LaWallet NWC to ${VERSION}" | |
| git push --force-with-lease origin "${BRANCH}" | |
| BODY_FILE="$(mktemp)" | |
| { | |
| echo "Updates the Umbrel package for LaWallet NWC ${VERSION}." | |
| echo | |
| echo "- Sets the Umbrel app version to ${VERSION}" | |
| echo "- Updates Docker image references to ${IMAGE}" | |
| echo "- Keeps the local regtest smoke stack on the same image tag" | |
| if [ -n "${SOURCE_REPOSITORY}" ]; then | |
| echo | |
| echo "Triggered by ${SOURCE_REPOSITORY}." | |
| fi | |
| if [ -n "${SOURCE_RUN_URL}" ]; then | |
| echo "Source run: ${SOURCE_RUN_URL}" | |
| fi | |
| } > "${BODY_FILE}" | |
| if gh pr view "${BRANCH}" --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1; then | |
| gh pr edit "${BRANCH}" \ | |
| --repo "${GITHUB_REPOSITORY}" \ | |
| --title "Update LaWallet NWC to ${VERSION}" \ | |
| --body-file "${BODY_FILE}" | |
| else | |
| gh pr create \ | |
| --repo "${GITHUB_REPOSITORY}" \ | |
| --base master \ | |
| --head "${BRANCH}" \ | |
| --title "Update LaWallet NWC to ${VERSION}" \ | |
| --body-file "${BODY_FILE}" | |
| fi | |
| PR_URL="$(gh pr view "${BRANCH}" --repo "${GITHUB_REPOSITORY}" --json url --jq .url)" | |
| echo "Merging ${PR_URL}" | |
| gh pr merge "${PR_URL}" \ | |
| --repo "${GITHUB_REPOSITORY}" \ | |
| --squash \ | |
| --delete-branch \ | |
| --subject "Update LaWallet NWC to ${VERSION}" \ | |
| --body "Automated Umbrel package update for ${IMAGE}." |