diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 000000000..17462742a --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,453 @@ +# Build VStar documentation and publish it to the gh-pages branch under +# docs/vstar/snapshot/ -- from the snapshot release tag +# docs/vstar/release/ -- from the latest semantic-version tag +# +# Publishes: +# docs/vstar/{snapshot,release}/user_manual/VStarUserManual.pdf +# docs/vstar/{snapshot,release}/plugin/*.pdf (plugin docs + plugin dev guide) +# +# Triggers: +# - Any GitHub release publish (snapshot release or stable X.Y.Z release) +# - Manual dispatch (with optional choice of which set to refresh) +# +# See: https://github.com/AAVSO/VStar/issues/592 + +name: Docs + +on: + release: + types: [published] + workflow_dispatch: + inputs: + target: + description: 'Which doc set(s) to refresh' + required: true + default: 'both' + type: choice + options: + - both + - snapshot + - release + +permissions: + contents: write + +jobs: + docs: + runs-on: ubuntu-latest + timeout-minutes: 20 + name: Publish documentation PDFs + + steps: + - name: Decide which targets to build + id: targets + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + T="${{ inputs.target }}" + else + T="both" + fi + case "$T" in + snapshot) BUILD_SNAPSHOT=true; BUILD_RELEASE=false ;; + release) BUILD_SNAPSHOT=false; BUILD_RELEASE=true ;; + both|*) BUILD_SNAPSHOT=true; BUILD_RELEASE=true ;; + esac + echo "build_snapshot=$BUILD_SNAPSHOT" >> "$GITHUB_OUTPUT" + echo "build_release=$BUILD_RELEASE" >> "$GITHUB_OUTPUT" + echo "Targets: snapshot=$BUILD_SNAPSHOT release=$BUILD_RELEASE" + + - name: Resolve snapshot ref + id: snapref + if: steps.targets.outputs.build_snapshot == 'true' + run: | + if git ls-remote --tags https://github.com/${{ github.repository }}.git refs/tags/snapshot | grep -q .; then + echo "ref=refs/tags/snapshot" >> "$GITHUB_OUTPUT" + else + echo "ref=refs/heads/master" >> "$GITHUB_OUTPUT" + fi + + - name: Resolve latest stable release tag + id: relref + if: steps.targets.outputs.build_release == 'true' + run: | + TAG=$(git ls-remote --tags https://github.com/${{ github.repository }}.git \ + | awk '{print $2}' \ + | sed 's|refs/tags/||;s|\^{}||' \ + | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' \ + | sort -V \ + | tail -1) + if [ -z "$TAG" ]; then + echo "No semantic-version tag found; skipping release docs." + echo "found=false" >> "$GITHUB_OUTPUT" + else + echo "Latest stable release tag: $TAG" + echo "found=true" >> "$GITHUB_OUTPUT" + echo "tag=$TAG" >> "$GITHUB_OUTPUT" + fi + + # ---------- Snapshot ---------- + - name: Checkout snapshot source + if: steps.targets.outputs.build_snapshot == 'true' + uses: actions/checkout@v4 + with: + ref: ${{ steps.snapref.outputs.ref }} + path: src_snapshot + + - name: Capture snapshot metadata + if: steps.targets.outputs.build_snapshot == 'true' + id: snapmeta + working-directory: src_snapshot + run: | + SHA=$(git rev-parse HEAD) + SHORT=$(git rev-parse --short=8 HEAD) + CDATE=$(git log -1 --format=%cI HEAD | cut -dT -f1) + echo "sha=$SHA" >> "$GITHUB_OUTPUT" + echo "short=$SHORT" >> "$GITHUB_OUTPUT" + echo "cdate=$CDATE" >> "$GITHUB_OUTPUT" + + # ---------- Release ---------- + - name: Checkout release source + if: steps.targets.outputs.build_release == 'true' && steps.relref.outputs.found == 'true' + uses: actions/checkout@v4 + with: + ref: refs/tags/${{ steps.relref.outputs.tag }} + path: src_release + + - name: Capture release metadata + if: steps.targets.outputs.build_release == 'true' && steps.relref.outputs.found == 'true' + id: relmeta + working-directory: src_release + run: | + SHA=$(git rev-parse HEAD) + SHORT=$(git rev-parse --short=8 HEAD) + CDATE=$(git log -1 --format=%cI HEAD | cut -dT -f1) + echo "sha=$SHA" >> "$GITHUB_OUTPUT" + echo "short=$SHORT" >> "$GITHUB_OUTPUT" + echo "cdate=$CDATE" >> "$GITHUB_OUTPUT" + + # ---------- Publish to gh-pages ---------- + - name: Checkout gh-pages + uses: actions/checkout@v4 + with: + ref: gh-pages + path: _site + + - name: Stage docs into gh-pages worktree + run: | + DATE=$(date -u +%Y-%m-%d) + mkdir -p _site/docs/vstar _site/docs/data + + if [ "${{ steps.targets.outputs.build_snapshot }}" = "true" ]; then + rm -rf _site/docs/vstar/snapshot + mkdir -p _site/docs/vstar/snapshot/user_manual + mkdir -p _site/docs/vstar/snapshot/plugin + if [ -f src_snapshot/doc/user_manual/VStarUserManual.pdf ]; then + cp src_snapshot/doc/user_manual/VStarUserManual.pdf \ + _site/docs/vstar/snapshot/user_manual/ + fi + if ls src_snapshot/plugin/doc/*.pdf 1>/dev/null 2>&1; then + cp src_snapshot/plugin/doc/*.pdf \ + _site/docs/vstar/snapshot/plugin/ + fi + fi + + if [ "${{ steps.targets.outputs.build_release }}" = "true" ] && \ + [ "${{ steps.relref.outputs.found }}" = "true" ]; then + rm -rf _site/docs/vstar/release + mkdir -p _site/docs/vstar/release/user_manual + mkdir -p _site/docs/vstar/release/plugin + if [ -f src_release/doc/user_manual/VStarUserManual.pdf ]; then + cp src_release/doc/user_manual/VStarUserManual.pdf \ + _site/docs/vstar/release/user_manual/ + fi + if ls src_release/plugin/doc/*.pdf 1>/dev/null 2>&1; then + cp src_release/plugin/doc/*.pdf \ + _site/docs/vstar/release/plugin/ + fi + fi + + # Write (or refresh) the docs landing page. + cat > _site/docs/index.html <<'HTML' + + + + + +VStar — Documentation + + + + +
+

VStar — Documentation

+

User manual, plugin development guide, and individual plugin docs

+ ← Back to VStar Project Hub +
+ +
+ +

Snapshot (development)

+ +
+

User Manual

+
Loading…
+ +
+ +
+

Plugin Development Guide

+ +
+ +
+

Plugin Docs

+ +
+ +

Latest stable release

+ +
+

User Manual

+
Loading…
+ +
+ +
+

Plugin Development Guide

+ +
+ +
+

Plugin Docs

+ +
+ +

+ Snapshot docs track the latest snapshot release tag. + Release docs track the latest semantic-version tag (e.g. X.Y.Z). + Both are refreshed automatically by GitHub Actions. +

+ +
+ + + + + + + +HTML + + # Merge new metadata with existing data/docs.json so a snapshot-only or + # release-only run doesn't clobber the other set. + python3 - "$DATE" \ + "${{ steps.targets.outputs.build_snapshot }}" \ + "${{ steps.snapmeta.outputs.sha }}" \ + "${{ steps.snapmeta.outputs.short }}" \ + "${{ steps.snapmeta.outputs.cdate }}" \ + "${{ steps.targets.outputs.build_release }}" \ + "${{ steps.relref.outputs.found }}" \ + "${{ steps.relref.outputs.tag }}" \ + "${{ steps.relmeta.outputs.sha }}" \ + "${{ steps.relmeta.outputs.short }}" \ + "${{ steps.relmeta.outputs.cdate }}" <<'PY' + import json, os, sys + date, do_snap, s_sha, s_short, s_cdate, do_rel, rel_found, r_tag, r_sha, r_short, r_cdate = sys.argv[1:] + path = "_site/docs/data/docs.json" + try: + with open(path) as f: + data = json.load(f) + except (OSError, ValueError): + data = {} + data["updated"] = date + if do_snap == "true": + data["snapshot"] = { + "commit": s_sha, "commit_short": s_short, + "commit_date": s_cdate, "generated": date, + "path": "vstar/snapshot/", + } + if do_rel == "true" and rel_found == "true": + data["release"] = { + "tag": r_tag, "commit": r_sha, "commit_short": r_short, + "commit_date": r_cdate, "generated": date, + "path": "vstar/release/", + } + with open(path, "w") as f: + json.dump(data, f, indent=2) + f.write("\n") + print(json.dumps(data, indent=2)) + PY + + - name: Commit and push to gh-pages + working-directory: _site + run: | + DATE=$(date -u +%Y-%m-%d) + git config user.email "github-actions[bot]@users.noreply.github.com" + git config user.name "github-actions[bot]" + git add -A + if git diff --cached --quiet; then + echo "No documentation changes to publish." + exit 0 + fi + SUMMARY="Update docs" + if [ "${{ steps.targets.outputs.build_snapshot }}" = "true" ] && [ "${{ steps.targets.outputs.build_release }}" = "true" ]; then + SUMMARY="Update docs (snapshot ${{ steps.snapmeta.outputs.short }} + release ${{ steps.relref.outputs.tag }})" + elif [ "${{ steps.targets.outputs.build_snapshot }}" = "true" ]; then + SUMMARY="Update snapshot docs (${{ steps.snapmeta.outputs.short }})" + elif [ "${{ steps.targets.outputs.build_release }}" = "true" ]; then + SUMMARY="Update release docs (${{ steps.relref.outputs.tag }})" + fi + git commit -m "${SUMMARY} [${DATE}]" + for i in 1 2 3; do + git pull --rebase origin gh-pages && git push origin gh-pages && break + echo "Push attempt $i failed, retrying in $((i * 5))s..." + sleep $((i * 5)) + done + + - name: Step summary + if: always() + run: | + cat >> "$GITHUB_STEP_SUMMARY" <> "$GITHUB_OUTPUT" diff --git a/.github/workflows/daily-release.yml b/.github/workflows/snapshot-release.yml similarity index 100% rename from .github/workflows/daily-release.yml rename to .github/workflows/snapshot-release.yml diff --git a/src/org/aavso/tools/vstar/util/help/Help.java b/src/org/aavso/tools/vstar/util/help/Help.java index 3be105520..7e745ceca 100644 --- a/src/org/aavso/tools/vstar/util/help/Help.java +++ b/src/org/aavso/tools/vstar/util/help/Help.java @@ -47,7 +47,7 @@ public static String getAAVSOtextFormatSinkHelpPage() { * Open the VStar manual page. */ public static void openVStarManual() { - openHelpURLInWebBrowser("https://github.com/AAVSO/VStar/blob/master/doc/user_manual/VStarUserManual.pdf"); + openHelpURLInWebBrowser("https://aavso.github.io/VStar/docs/vstar/release/user_manual/VStarUserManual.pdf"); } /** @@ -61,7 +61,7 @@ public static void openVStarWebPage() { * Plug-in help */ public static void openPluginHelp(String plugin_doc_name) { - String urlStr = "https://github.com/AAVSO/VStar/tree/master/plugin/doc/"; + String urlStr = "https://aavso.github.io/VStar/docs/vstar/release/plugin/"; if (plugin_doc_name != null) { // plugin_doc_name can be a file name (without path) resided in the base plug-in doc directory. // In this case it may contain spaces and other special characters.