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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
22 changes: 13 additions & 9 deletions .github/workflows/deploy-site.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ on:
paths:
- "web/**"
- "Resources/Marketing/app-icon.png"
- "Tools/**"
- "Localization/**"
- "docs/**"
- "DemoLab/publication.json"
- "DemoLab/Localization/**"
- "DemoLab/scenes/**"
- ".github/workflows/deploy-site.yml"
workflow_dispatch:

Expand Down Expand Up @@ -48,6 +54,11 @@ jobs:
echo "should-deploy=true" >> "$GITHUB_OUTPUT"
echo "version=$RELEASE_VERSION" >> "$GITHUB_OUTPUT"

- uses: swift-actions/setup-swift@v2
if: steps.release.outputs.should-deploy == 'true'
with:
swift-version: "6.2"

- name: Assemble site
if: steps.release.outputs.should-deploy == 'true'
env:
Expand All @@ -64,15 +75,8 @@ jobs:
# index.html (the page also resolves this live via the API).
echo "Latest version: $VERSION"

cp web/*.html web/*.css "$SITE/"
cp web/*.mp4 web/*.jpg "$SITE/" 2>/dev/null || true
sed -i "s/__VERSION__/${VERSION}/g" "$SITE/index.html"
cp Resources/Marketing/app-icon.png "$SITE/icon.png"

# Cache-bust the stylesheet so a CSS change is never masked by a
# stale browser cache (HTML + CSS stay in lockstep per deploy).
BUST="${GITHUB_SHA:0:8}"
sed -i "s#\"./style.css\"#\"./style.css?v=${BUST}\"#g" "$SITE"/*.html
swift test --package-path Tools
swift run --package-path Tools tatami-tools build-site --output "$SITE" --version "$VERSION"

# Preserve the Sparkle feed. GitHub Pages replaces the whole site on
# deploy, so re-publish appcast.xml. The canonical copy is the latest
Expand Down
92 changes: 10 additions & 82 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ jobs:

- uses: jdx/mise-action@v4

- name: Build and test automation tools
run: |
swift test --package-path Tools
swift build --package-path Tools -c release

- name: Import Developer ID certificate
env:
CERT_P12_BASE64: ${{ secrets.DEVELOPER_ID_P12_BASE64 }}
Expand Down Expand Up @@ -132,8 +137,8 @@ jobs:
--issuer "$AC_API_ISSUER_ID" \
--output-format json --wait)"
echo "$SUBMIT_JSON"
SUB_ID="$(echo "$SUBMIT_JSON" | python3 -c 'import sys, json; print(json.load(sys.stdin)["id"])')"
SUB_STATUS="$(echo "$SUBMIT_JSON" | python3 -c 'import sys, json; print(json.load(sys.stdin)["status"])')"
SUB_ID="$(echo "$SUBMIT_JSON" | Tools/.build/release/tatami-tools json-field id)"
SUB_STATUS="$(echo "$SUBMIT_JSON" | Tools/.build/release/tatami-tools json-field status)"
if [ "$SUB_STATUS" != "Accepted" ]; then
echo "Notarization failed with status: $SUB_STATUS. Fetching log:"
xcrun notarytool log "$SUB_ID" \
Expand Down Expand Up @@ -172,73 +177,8 @@ jobs:
# stopping at the previous minor (those users already had it). The
# website / GitHub release show only this version's own section —
# CHANGELOG.md stays one-section-per-version, no hand-carried notes.
APPCAST="$APPCAST" VERSION="$VERSION" python3 - <<'PY'
import os, re, html as H

version = os.environ["VERSION"]
minor = ".".join(version.split(".")[:2]) # 1.3.3 -> 1.3

# Split CHANGELOG into (heading, body-lines) version sections.
sections, cur = [], None
for line in open("CHANGELOG.md", encoding="utf-8").read().splitlines():
if line.startswith("## "):
cur = {"head": line[3:].strip(), "lines": []}
sections.append(cur)
elif cur is not None:
cur["lines"].append(line)

def secver(head):
m = re.match(r"v?(\d+\.\d+\.\d+)", head)
return m.group(1) if m else None

collected, started = [], False
for s in sections:
v = secver(s["head"])
if v == version:
started = True
if not started:
continue
if v is None or ".".join(v.split(".")[:2]) != minor:
break
collected.append(s)

def inline(s):
s = H.escape(s)
s = re.sub(r"`([^`]+)`", r"<code>\1</code>", s)
s = re.sub(r"\*\*([^*]+)\*\*", r"<strong>\1</strong>", s)
s = re.sub(r"\[([^\]]+)\]\(([^)]+)\)", r'<a href="\2">\1</a>', s)
s = re.sub(r"(?<!\*)\*([^*]+)\*(?!\*)", r"<em>\1</em>", s)
return s

out, in_ul = [], False
for s in collected:
if in_ul: out.append("</ul>"); in_ul = False
out.append("<h2>" + inline(s["head"]) + "</h2>")
for line in s["lines"]:
if line.startswith("### "):
if in_ul: out.append("</ul>"); in_ul = False
out.append("<h3>" + inline(line[4:].strip()) + "</h3>")
elif line.startswith("- "):
if not in_ul: out.append("<ul>"); in_ul = True
out.append("<li>" + inline(line[2:].strip()) + "</li>")
elif line.strip() == "":
if in_ul: out.append("</ul>"); in_ul = False
else:
if in_ul: out.append("</ul>"); in_ul = False
out.append("<p>" + inline(line.strip()) + "</p>")
if in_ul: out.append("</ul>")

html = "\n".join(out).strip()
appcast = os.environ["APPCAST"]
xml = open(appcast, encoding="utf-8").read()
if html and "<description>" not in xml:
desc = "<description><![CDATA[\n" + html + "\n]]></description>\n "
xml = xml.replace("</item>", desc + "</item>", 1)
open(appcast, "w", encoding="utf-8").write(xml)
print("appcast: embedded release notes (%d section(s))" % len(collected))
else:
print("appcast: skipped (no notes or description already present)")
PY
Tools/.build/release/tatami-tools embed-release-notes \
--appcast "$APPCAST" --version "$VERSION"

- name: Build release notes from CHANGELOG
env:
Expand Down Expand Up @@ -323,19 +263,7 @@ jobs:
run: |
set -euo pipefail
mkdir -p "$RUNNER_TEMP/site"
# Static pages (configuration.html / releases.html render their source
# of truth at runtime; index.html gets the release version injected).
cp web/*.html web/*.css "$RUNNER_TEMP/site/"
cp web/*.mp4 web/*.jpg "$RUNNER_TEMP/site/" 2>/dev/null || true
sed "s/__VERSION__/${VERSION}/g" web/index.html > "$RUNNER_TEMP/site/index.html"
cp Resources/Marketing/app-icon.png "$RUNNER_TEMP/site/icon.png"
# Cache-bust the stylesheet so a CSS change is never masked by a
# stale browser cache.
BUST="${GITHUB_SHA:0:8}"
# `sed -i` with no backup suffix is GNU-only; this job runs on macOS,
# whose BSD sed needs `-i.bak` (which GNU sed also accepts). Clean up.
sed -i.bak "s#\"./style.css\"#\"./style.css?v=${BUST}\"#g" "$RUNNER_TEMP/site"/*.html
rm -f "$RUNNER_TEMP/site"/*.html.bak
Tools/.build/release/tatami-tools build-site --output "$RUNNER_TEMP/site" --version "$VERSION"
# Sparkle feed.
cp "$RUNNER_TEMP/release/appcast.xml" "$RUNNER_TEMP/site/appcast.xml"

Expand Down
32 changes: 32 additions & 0 deletions .github/workflows/tools.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Automation tools

on:
pull_request:
paths:
- "Tools/**"
- "DemoLab/**"
- "Localization/**"
- "docs/**"
- "README*.md"
- "NOTICE*.md"
- "THIRD_PARTY_NOTICES*.md"
- "web/**"
- ".github/workflows/tools.yml"
workflow_dispatch:

permissions:
contents: read

jobs:
portable-tools:
runs-on: ubuntu-latest
container: swift:6.2-noble
steps:
- uses: actions/checkout@v6
- name: Test native automation and generated content
run: |
swift test --package-path Tools
swift run --package-path Tools tatami-tools build-tool-notices --check
swift run --package-path Tools tatami-tools build-docs --check
swift run --package-path Tools tatami-tools localize-scenes --check
swift run --package-path Tools tatami-tools build-site --output /tmp/tatami-site
7 changes: 7 additions & 0 deletions DemoLab/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.build/
recordings/
*.mov
.swiftpm/
.sync/

__pycache__/
Loading