From 81d28d0af4786bf78b070ebe62f1b7ed8891d1ab Mon Sep 17 00:00:00 2001 From: Alessandro Digilio Date: Tue, 17 Feb 2026 14:37:20 +0100 Subject: [PATCH 1/5] fix: vendor docs workflow for public github pages --- .github/scripts/docs/fix_asset_paths.py | 43 +++++ .github/scripts/docs/inject_mermaid.sh | 84 ++++++++++ .github/workflows/backend-docs.yml | 204 ++++++++++++++++++++++++ .github/workflows/docs-build.yml | 9 +- 4 files changed, 339 insertions(+), 1 deletion(-) create mode 100644 .github/scripts/docs/fix_asset_paths.py create mode 100644 .github/scripts/docs/inject_mermaid.sh create mode 100644 .github/workflows/backend-docs.yml diff --git a/.github/scripts/docs/fix_asset_paths.py b/.github/scripts/docs/fix_asset_paths.py new file mode 100644 index 0000000..9a1ed76 --- /dev/null +++ b/.github/scripts/docs/fix_asset_paths.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +import io +import os +import sys + +def rewrite_paths(path: str) -> bool: + if not os.path.isfile(path): + return False + with io.open(path, 'r', encoding='utf-8', errors='ignore') as f: + s = f.read() + + # Markdown: ](/docs/... -> ](./docs/... + s = s.replace('](/docs/', '](./docs/') + # Markdown escaped (embedded JSON): ](\/docs\/ -> ](./docs/ + s = s.replace('](\\/docs\\/', '](./docs/') + + # HTML attributes + s = s.replace('src="/docs/', 'src="./docs/') + s = s.replace("src='/docs/", "src='./docs/") + s = s.replace('href="/docs/', 'href="./docs/') + s = s.replace("href='/docs/", "href='./docs/") + + # Generic occurrences in embedded JSON: \/docs\/ -> \.\/docs\/ + s = s.replace('\\/docs\\/', '\\./docs\\/') + + with io.open(path, 'w', encoding='utf-8') as f: + f.write(s) + print(f"Rewrote /docs -> ./docs in {path}") + return True + + +def main(argv): + if len(argv) < 2: + print("Usage: fix_asset_paths.py ", file=sys.stderr) + return 2 + path = argv[1] + ok = rewrite_paths(path) + return 0 if ok else 0 + + +if __name__ == '__main__': + raise SystemExit(main(sys.argv)) + diff --git a/.github/scripts/docs/inject_mermaid.sh b/.github/scripts/docs/inject_mermaid.sh new file mode 100644 index 0000000..e7df7f6 --- /dev/null +++ b/.github/scripts/docs/inject_mermaid.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Usage: +# bash scripts/docs/inject_mermaid.sh [MERMAID_VERSION] +# or with env vars INDEX and MERMAID_VERSION + +INDEX="${1:-${INDEX:-}}" +MERMAID_VERSION="${2:-${MERMAID_VERSION:-10}}" + +if [[ -z "${INDEX}" ]]; then + echo "INDEX path not provided" >&2 + exit 1 +fi + +if [[ ! -f "${INDEX}" ]]; then + echo "Index not found: ${INDEX}" + exit 0 +fi + +export INDEX MERMAID_VERSION +python3 - << 'PY' +import os, io + +p = os.environ['INDEX'] +version = os.environ.get('MERMAID_VERSION', '10') + +with io.open(p, 'r', encoding='utf-8', errors='ignore') as f: + s = f.read() + +if '' in s: + print('Mermaid already injected; skipping.') +else: + inject = '''\ + + + + +''' + inject = inject.replace('__VER__', version) + + if '' in s: + s = s.replace('', inject + '\n', 1) + else: + s = s + inject + + with io.open(p, 'w', encoding='utf-8') as f: + f.write(s) + print('Injected Mermaid support into', p) +PY + diff --git a/.github/workflows/backend-docs.yml b/.github/workflows/backend-docs.yml new file mode 100644 index 0000000..aeb1ad0 --- /dev/null +++ b/.github/workflows/backend-docs.yml @@ -0,0 +1,204 @@ +name: backend-docs + +on: + workflow_call: + inputs: + docs_dir: + description: Directory contenente description.md e openapi + required: false + default: "docs" + type: string + openapi_path: + description: Path a openapi (se non usare autodetect) + required: false + default: "" + type: string + mermaid_version: + description: Versione di Mermaid JS da iniettare (es. 10 o 10.9.1) + required: false + default: "10" + type: string + description_md: + description: Path a description.md (se diverso da default) + required: false + default: "" + type: string + output_dir: + description: Directory di output static site (per Pages) + required: false + default: "site" + type: string + node_version: + description: Versione Node per npx (@redocly/cli/marked) + required: false + default: "20" + type: string + deploy_pages: + description: Esegui deploy su GitHub Pages + required: false + default: "true" + type: string + checkout_submodules: + description: Checkout Git submodules as part of docs (true/false) + required: false + default: "false" + type: string + publish: + description: When 'true' uploads artifact and deploys Pages + required: false + default: "true" + type: string + secrets: + SSH_PRIVATE_KEY: + description: Optional private SSH key for private Git dependencies (submodules, refs) + required: false + ssh_known_hosts: + description: Optional known_hosts entries (defaults to github.com via ssh-keyscan) + required: false + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build-and-publish-docs: + name: Build Redoc HTML and Publish + runs-on: ubuntu-22.04 + timeout-minutes: 20 + defaults: + run: + working-directory: ${{ github.workspace }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: ${{ inputs.checkout_submodules == 'true' }} + # If you use submodules to pull docs from private repos, set submodules: true in the caller + # with: + # submodules: true + + # SSH for private submodules or git-based $ref sources + - name: Setup ssh-agent with provided key + uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: | + ${{ secrets.SSH_PRIVATE_KEY }} + + - name: Configure known_hosts (github.com) + shell: bash + run: | + set -euo pipefail + mkdir -p ~/.ssh + touch ~/.ssh/known_hosts + chmod 600 ~/.ssh/known_hosts + if [[ -n "${{ secrets.ssh_known_hosts }}" ]]; then + printf "%s\n" "${{ secrets.ssh_known_hosts }}" >> ~/.ssh/known_hosts + else + ssh-keyscan -H -t rsa,ecdsa,ed25519 github.com >> ~/.ssh/known_hosts 2>/dev/null || true + fi + + - name: Checkout existing Pages (gh-pages) + if: ${{ inputs.publish == 'true' && (inputs.deploy_pages || 'true') == 'true' }} + uses: actions/checkout@v4 + continue-on-error: true + with: + ref: gh-pages + path: .gh-pages-prev + + - name: Setup Node.js ${{ inputs.node_version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ inputs.node_version || '20' }} + + - name: Resolve BRANCH_DIR (head_ref or ref_name) + id: branchdir + shell: bash + run: | + set -euo pipefail + if [[ -n "${GITHUB_HEAD_REF:-}" ]]; then + RAW="$GITHUB_HEAD_REF" + else + RAW="$GITHUB_REF_NAME" + fi + SANITIZED="${RAW//\//-}" + echo "Resolved BRANCH values: raw='$RAW' sanitized='$SANITIZED'" + echo "::notice title=BRANCH_DIR::Using '$SANITIZED' (raw: '$RAW')" + echo "BRANCH_RAW=$RAW" >> "$GITHUB_ENV" + echo "BRANCH_DIR=$SANITIZED" >> "$GITHUB_ENV" + echo "dir=$SANITIZED" >> "$GITHUB_OUTPUT" + echo "raw=$RAW" >> "$GITHUB_OUTPUT" + + - name: Build docs with @redocly/cli (bundle per branch) + shell: bash + run: | + set -euo pipefail + DOCS_DIR="${{ inputs.docs_dir || 'docs' }}" + OPENAPI="${{ inputs.openapi_path || '' }}" + OUT_DIR="${{ inputs.output_dir || 'site' }}" + BRANCH_DIR="${BRANCH_DIR}" + mkdir -p "$OUT_DIR" + if [[ -d .gh-pages-prev ]]; then + rsync -a --exclude '.git' .gh-pages-prev/ "$OUT_DIR/" || true + fi + if [[ -z "$OPENAPI" ]]; then + for f in "$DOCS_DIR"/openapi.yaml "$DOCS_DIR"/openapi.yml "$DOCS_DIR"/openapi.json; do + if [[ -f "$f" ]]; then OPENAPI="$f"; break; fi + done + fi + if [[ -z "$OPENAPI" || ! -f "$OPENAPI" ]]; then + echo "File OpenAPI non trovato (cerca in ${DOCS_DIR}/openapi.yaml|yml|json o specifica input openapi_path)" >&2 + exit 2 + fi + mkdir -p "$OUT_DIR/$BRANCH_DIR" + + npx -y @redocly/cli build-docs "$OPENAPI" -o "$OUT_DIR/$BRANCH_DIR/index.html" + rsync -a --include='*/' --include='*.png' --exclude='*' "$DOCS_DIR"/ "$OUT_DIR/$BRANCH_DIR/docs/" || true + + + - name: Fix asset paths in generated HTML (HTML + embedded JSON) + shell: bash + continue-on-error: true + run: | + set -euo pipefail + OUT_DIR="${{ inputs.output_dir || 'site' }}" + BRANCH_DIR="${BRANCH_DIR}" + INDEX="$OUT_DIR/$BRANCH_DIR/index.html" + + if [[ ! -f "$INDEX" ]]; then + echo "Index not found: $INDEX" + exit 0 + fi + python3 ".github/scripts/docs/fix_asset_paths.py" "$INDEX" + + - name: Enable Mermaid diagrams (inject script) + shell: bash + continue-on-error: true + run: | + set -euo pipefail + OUT_DIR="${{ inputs.output_dir || 'site' }}" + BRANCH_DIR="${BRANCH_DIR}" + INDEX="$OUT_DIR/$BRANCH_DIR/index.html" + MERMAID_VERSION="${{ inputs.mermaid_version || '10' }}" + bash ".github/scripts/docs/inject_mermaid.sh" "$INDEX" "$MERMAID_VERSION" + # --- publish gating (artifact + deploy) --- + + - name: Upload Pages artifact + if: ${{ inputs.publish == 'true' && (inputs.deploy_pages || 'true') == 'true' }} + uses: actions/upload-pages-artifact@v3 + with: + path: ${{ inputs.output_dir || 'site' }} + + - name: Deploy to GitHub Pages + if: ${{ inputs.publish == 'true' && (inputs.deploy_pages || 'true') == 'true' }} + id: deployment + uses: actions/deploy-pages@v4 + + - name: Skipping publish (publish='${{ inputs.publish }}', deploy_pages='${{ inputs.deploy_pages }}') + if: ${{ inputs.publish != 'true' || (inputs.deploy_pages || 'true') != 'true' }} + run: echo "Skipping artifact upload and deploy (publish=${{ inputs.publish }}, deploy_pages=${{ inputs.deploy_pages }})" diff --git a/.github/workflows/docs-build.yml b/.github/workflows/docs-build.yml index a890573..c1365e9 100644 --- a/.github/workflows/docs-build.yml +++ b/.github/workflows/docs-build.yml @@ -6,10 +6,17 @@ on: pull_request: paths: - "docs/**" + - "openapi.json" - ".github/workflows/docs-build.yml" + - ".github/workflows/backend-docs.yml" + - ".github/scripts/docs/**" jobs: build: name: Reusable Docs Build - uses: FlowPay/ci-templates/.github/workflows/backend-docs.yml@main + uses: ./.github/workflows/backend-docs.yml + with: + docs_dir: docs + openapi_path: openapi.json + publish: ${{ github.event_name == 'push' && 'true' || 'false' }} secrets: inherit From 67fcb91f849418380f9bacb9488a243360f74c41 Mon Sep 17 00:00:00 2001 From: Alessandro Digilio Date: Tue, 17 Feb 2026 14:42:46 +0100 Subject: [PATCH 2/5] fix: remove ssh dependency from docs pages workflow --- .github/workflows/backend-docs.yml | 27 --------------------------- .github/workflows/docs-build.yml | 1 - 2 files changed, 28 deletions(-) diff --git a/.github/workflows/backend-docs.yml b/.github/workflows/backend-docs.yml index aeb1ad0..a3b1970 100644 --- a/.github/workflows/backend-docs.yml +++ b/.github/workflows/backend-docs.yml @@ -48,13 +48,6 @@ on: required: false default: "true" type: string - secrets: - SSH_PRIVATE_KEY: - description: Optional private SSH key for private Git dependencies (submodules, refs) - required: false - ssh_known_hosts: - description: Optional known_hosts entries (defaults to github.com via ssh-keyscan) - required: false permissions: contents: read @@ -83,26 +76,6 @@ jobs: # with: # submodules: true - # SSH for private submodules or git-based $ref sources - - name: Setup ssh-agent with provided key - uses: webfactory/ssh-agent@v0.9.0 - with: - ssh-private-key: | - ${{ secrets.SSH_PRIVATE_KEY }} - - - name: Configure known_hosts (github.com) - shell: bash - run: | - set -euo pipefail - mkdir -p ~/.ssh - touch ~/.ssh/known_hosts - chmod 600 ~/.ssh/known_hosts - if [[ -n "${{ secrets.ssh_known_hosts }}" ]]; then - printf "%s\n" "${{ secrets.ssh_known_hosts }}" >> ~/.ssh/known_hosts - else - ssh-keyscan -H -t rsa,ecdsa,ed25519 github.com >> ~/.ssh/known_hosts 2>/dev/null || true - fi - - name: Checkout existing Pages (gh-pages) if: ${{ inputs.publish == 'true' && (inputs.deploy_pages || 'true') == 'true' }} uses: actions/checkout@v4 diff --git a/.github/workflows/docs-build.yml b/.github/workflows/docs-build.yml index c1365e9..8221ddc 100644 --- a/.github/workflows/docs-build.yml +++ b/.github/workflows/docs-build.yml @@ -19,4 +19,3 @@ jobs: docs_dir: docs openapi_path: openapi.json publish: ${{ github.event_name == 'push' && 'true' || 'false' }} - secrets: inherit From c780bff942834d73e370f876aed2f7187972e1f3 Mon Sep 17 00:00:00 2001 From: Alessandro Digilio Date: Tue, 17 Feb 2026 14:50:12 +0100 Subject: [PATCH 3/5] fix: avoid duplicate pages artifacts on workflow reruns --- .github/workflows/backend-docs.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/backend-docs.yml b/.github/workflows/backend-docs.yml index a3b1970..b704b7e 100644 --- a/.github/workflows/backend-docs.yml +++ b/.github/workflows/backend-docs.yml @@ -165,12 +165,15 @@ jobs: if: ${{ inputs.publish == 'true' && (inputs.deploy_pages || 'true') == 'true' }} uses: actions/upload-pages-artifact@v3 with: + name: github-pages-${{ github.run_id }}-${{ github.run_attempt }} path: ${{ inputs.output_dir || 'site' }} - name: Deploy to GitHub Pages if: ${{ inputs.publish == 'true' && (inputs.deploy_pages || 'true') == 'true' }} id: deployment uses: actions/deploy-pages@v4 + with: + artifact_name: github-pages-${{ github.run_id }}-${{ github.run_attempt }} - name: Skipping publish (publish='${{ inputs.publish }}', deploy_pages='${{ inputs.deploy_pages }}') if: ${{ inputs.publish != 'true' || (inputs.deploy_pages || 'true') != 'true' }} From aa0fc2d9e76437dbc4f507c93efaa64172a4e028 Mon Sep 17 00:00:00 2001 From: Alessandro Digilio Date: Tue, 17 Feb 2026 14:55:21 +0100 Subject: [PATCH 4/5] feat: print github pages urls in workflow output --- .github/workflows/backend-docs.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/backend-docs.yml b/.github/workflows/backend-docs.yml index b704b7e..93e7790 100644 --- a/.github/workflows/backend-docs.yml +++ b/.github/workflows/backend-docs.yml @@ -175,6 +175,21 @@ jobs: with: artifact_name: github-pages-${{ github.run_id }}-${{ github.run_attempt }} + - name: Report GitHub Pages URLs + if: ${{ inputs.publish == 'true' && (inputs.deploy_pages || 'true') == 'true' && steps.deployment.outputs.page_url != '' }} + shell: bash + run: | + set -euo pipefail + BASE_URL="${{ steps.deployment.outputs.page_url }}" + BRANCH_URL="${BASE_URL%/}/${BRANCH_DIR}/" + echo "::notice title=Pages base URL::${BASE_URL}" + echo "::notice title=Pages branch URL::${BRANCH_URL}" + { + echo "### GitHub Pages" + echo "- Base URL: ${BASE_URL}" + echo "- Branch URL (${BRANCH_RAW}): ${BRANCH_URL}" + } >> "$GITHUB_STEP_SUMMARY" + - name: Skipping publish (publish='${{ inputs.publish }}', deploy_pages='${{ inputs.deploy_pages }}') if: ${{ inputs.publish != 'true' || (inputs.deploy_pages || 'true') != 'true' }} run: echo "Skipping artifact upload and deploy (publish=${{ inputs.publish }}, deploy_pages=${{ inputs.deploy_pages }})" From 93bef16dbb2b348e5e29de1694cb81e342e0ff40 Mon Sep 17 00:00:00 2001 From: Alessandro Digilio Date: Tue, 17 Feb 2026 14:59:07 +0100 Subject: [PATCH 5/5] fix: clean docs workflow annotations --- .github/workflows/backend-docs.yml | 16 ++++++++++++++-- .gitignore | 1 + .tmp/gateway.client | 1 - 3 files changed, 15 insertions(+), 3 deletions(-) delete mode 160000 .tmp/gateway.client diff --git a/.github/workflows/backend-docs.yml b/.github/workflows/backend-docs.yml index 93e7790..2e2d100 100644 --- a/.github/workflows/backend-docs.yml +++ b/.github/workflows/backend-docs.yml @@ -76,10 +76,22 @@ jobs: # with: # submodules: true - - name: Checkout existing Pages (gh-pages) + - name: Check gh-pages branch availability if: ${{ inputs.publish == 'true' && (inputs.deploy_pages || 'true') == 'true' }} + id: ghpages + shell: bash + run: | + set -euo pipefail + if git ls-remote --exit-code --heads "https://github.com/${GITHUB_REPOSITORY}.git" gh-pages >/dev/null 2>&1; then + echo "exists=true" >> "$GITHUB_OUTPUT" + else + echo "exists=false" >> "$GITHUB_OUTPUT" + echo "::notice title=gh-pages branch::No gh-pages branch found. Building from empty site state." + fi + + - name: Checkout existing Pages (gh-pages) + if: ${{ inputs.publish == 'true' && (inputs.deploy_pages || 'true') == 'true' && steps.ghpages.outputs.exists == 'true' }} uses: actions/checkout@v4 - continue-on-error: true with: ref: gh-pages path: .gh-pages-prev diff --git a/.gitignore b/.gitignore index f2b4d78..9b5881f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ openapi.html postman_collection.json Simplified Flow.pdf old-openapi.json +.tmp/ diff --git a/.tmp/gateway.client b/.tmp/gateway.client deleted file mode 160000 index 1f23fe2..0000000 --- a/.tmp/gateway.client +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1f23fe2ad053a98b667c925cfcd84cbb25b7e391