Skip to content

Commit fa741fb

Browse files
feat: docs-publish worfklow
1 parent dfc6ffa commit fa741fb

2 files changed

Lines changed: 185 additions & 264 deletions

File tree

.github/workflows/docs-publish.yml

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
# *******************************************************************************
2+
# Copyright (c) 2026 Contributors to the Eclipse Foundation
3+
#
4+
# See the NOTICE file(s) distributed with this work for additional
5+
# information regarding copyright ownership.
6+
#
7+
# This program and the accompanying materials are made available under the
8+
# terms of the Apache License Version 2.0 which is available at
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# SPDX-License-Identifier: Apache-2.0
12+
# *******************************************************************************
13+
14+
name: Publish Documentation
15+
16+
# Assuming you have one workflow that builds the documentation artifact (e.g., "PR"),
17+
# this workflow can be used to deploy the documentation to GitHub Pages in a versioned manner.
18+
# It also updates a versions.json file to keep track of available documentation versions and
19+
# comments on the PR with a link to the preview if applicable.
20+
# Note: this can be used with any documentation-building workflow, not only docs-as-code.
21+
22+
# It will use gh-pages branch internally to mix the new documentation with the existing one.
23+
# Use daily.yml to clean up old documentation versions (merged PRs).
24+
25+
# Usage:
26+
# on:
27+
# workflow_run:
28+
# workflows: ["PR"] # <-- name of the workflow that builds the documentation artifact
29+
# types:
30+
# - completed
31+
# jobs:
32+
# docs-deploy:
33+
# uses: eclipse-score/cicd-workflows/.github/workflows/copyright.yml@<RECENT_HASH_HERE>
34+
# permissions:
35+
# pages: write
36+
# id-token: write
37+
# contents: write
38+
# pull-requests: write
39+
40+
on:
41+
workflow_call:
42+
43+
concurrency:
44+
group: cicd-pages-deploy
45+
cancel-in-progress: false
46+
47+
jobs:
48+
docs-deploy:
49+
name: Deploy documentation to GitHub Pages
50+
if: github.event.workflow_run.conclusion == 'success'
51+
permissions:
52+
pages: write # publish to GitHub Pages
53+
id-token: write # to verify the deployment originates from an appropriate source
54+
contents: write # to update versions.json and commit to gh-pages
55+
pull-requests: write # to comment on PRs with preview link
56+
runs-on: ubuntu-latest
57+
steps:
58+
- name: Resolve build metadata
59+
id: metadata
60+
run: |
61+
EVENT_NAME="${{ github.event.workflow_run.event }}"
62+
PR_NUMBER="${{ github.event.workflow_run.pull_requests[0].number }}"
63+
REF_NAME="${{ github.event.workflow_run.head_branch }}"
64+
65+
if [[ "$EVENT_NAME" == "merge_group" ]]; then
66+
echo "should_deploy=false" >> "$GITHUB_OUTPUT"
67+
else
68+
echo "should_deploy=true" >> "$GITHUB_OUTPUT"
69+
fi
70+
71+
echo "event_name=$EVENT_NAME" >> "$GITHUB_OUTPUT"
72+
echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
73+
echo "ref_name=$REF_NAME" >> "$GITHUB_OUTPUT"
74+
75+
- name: Determine target folder
76+
if: steps.metadata.outputs.should_deploy == 'true'
77+
id: target
78+
run: |
79+
EVENT_NAME="${{ steps.metadata.outputs.event_name }}"
80+
if [[ "$EVENT_NAME" == "pull_request" ]]; then
81+
echo "folder=pr-${{ steps.metadata.outputs.pr_number }}" >> "$GITHUB_OUTPUT"
82+
else
83+
echo "folder=${{ steps.metadata.outputs.ref_name }}" >> "$GITHUB_OUTPUT"
84+
fi
85+
86+
- name: Checkout gh-pages
87+
if: steps.metadata.outputs.should_deploy == 'true'
88+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
89+
with:
90+
ref: gh-pages
91+
path: gh-pages-content
92+
93+
- name: Clean up old documentation
94+
if: steps.metadata.outputs.should_deploy == 'true'
95+
run: |
96+
rm -rf "gh-pages-content/${{ steps.target.outputs.folder }}"
97+
98+
- name: Download documentation artifact
99+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
100+
with:
101+
name: github-pages
102+
run-id: ${{ github.event.workflow_run.id }}
103+
github-token: ${{ github.token }}
104+
path: gh-pages-content/${{ steps.target.outputs.folder }}
105+
106+
- name: Ensure .nojekyll exists
107+
if: steps.metadata.outputs.should_deploy == 'true'
108+
run: touch gh-pages-content/.nojekyll
109+
110+
- name: Extend versions.json
111+
if: steps.metadata.outputs.should_deploy == 'true'
112+
run: |
113+
TARGET="${{ steps.target.outputs.folder }}"
114+
115+
# if versions.json does not exist, create it with an empty array as content
116+
if [ ! -f gh-pages-content/versions.json ]; then
117+
echo '[]' > gh-pages-content/versions.json
118+
fi
119+
120+
# Add new version entry to versions.json if it doesn't already exist
121+
if jq -e --arg v "$TARGET" 'map(select(.version == $v)) | length > 0' gh-pages-content/versions.json > /dev/null; then
122+
echo "Version '$TARGET' already exists in versions.json"
123+
else
124+
REPO_NAME=$(basename "${{ github.repository }}")
125+
OWNER_NAME="${{ github.repository_owner }}"
126+
PAGES_URL="https://${OWNER_NAME}.github.io/${REPO_NAME}"
127+
jq --arg v "$TARGET" --arg u "${PAGES_URL}/${TARGET}/" \
128+
'. + [{"version": $v, "url": $u}]' gh-pages-content/versions.json > gh-pages-content/tmp.json && mv gh-pages-content/tmp.json gh-pages-content/versions.json
129+
fi
130+
131+
- name: Commit and push changes to gh-pages
132+
if: steps.metadata.outputs.should_deploy == 'true'
133+
run: |
134+
cd gh-pages-content
135+
git config user.name "github-actions[bot]"
136+
git config user.email "github-actions[bot]@users.noreply.github.com"
137+
git add .
138+
git commit -m "Update documentation for ${{ steps.target.outputs.folder }}" || echo "No changes to commit"
139+
git push
140+
141+
- name: Create artifact from gh-pages
142+
if: steps.metadata.outputs.should_deploy == 'true'
143+
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
144+
with:
145+
path: gh-pages-content
146+
147+
- name: Deploy artifact to GitHub Pages
148+
if: steps.metadata.outputs.should_deploy == 'true'
149+
id: deploy-pages
150+
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
151+
152+
- name: Find existing PR comment
153+
if: steps.metadata.outputs.should_deploy == 'true' && steps.metadata.outputs.event_name == 'pull_request' && steps.metadata.outputs.pr_number != ''
154+
uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4.0.0
155+
id: fc
156+
with:
157+
issue-number: ${{ steps.metadata.outputs.pr_number }}
158+
comment-author: 'github-actions[bot]'
159+
body-includes: Documentation preview for this pull request
160+
161+
- name: Comment on PR with preview link
162+
if: steps.metadata.outputs.should_deploy == 'true' && steps.metadata.outputs.event_name == 'pull_request' && steps.metadata.outputs.pr_number != '' && steps.fc.outputs.comment-id == ''
163+
uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0
164+
with:
165+
issue-number: ${{ steps.metadata.outputs.pr_number }}
166+
body: |
167+
Documentation preview for this pull request is available at:
168+
**${{ steps.target.outputs.folder }}**: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/${{ steps.target.outputs.folder }}/

0 commit comments

Comments
 (0)