@@ -3,31 +3,24 @@ name: Build and Deploy mdBook
33# To update mdbook or plugin versions, edit versions.toml and the CI will automatically use them.
44
55on :
6- # Runs on pushes targeting the default branch
76 push :
87 branches : ["main"]
98
10- # Runs on pull requests for validation and preview deployment
119 pull_request :
1210 branches : ["main"]
1311
14- # Allows you to run this workflow manually from the Actions tab
1512 workflow_dispatch :
1613
17- # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
1814permissions :
19- contents : write # Needed for PR preview deployments
15+ contents : read
2016 pages : write
2117 id-token : write
22- pull-requests : write # Needed to comment on PRs
2318
24- # Allow only one concurrent deployment per PR or main
2519concurrency :
26- group : ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.event.number || 'main' }}
27- cancel-in-progress : true
20+ group : " pages "
21+ cancel-in-progress : false
2822
2923jobs :
30- # Build job - runs on both PRs and main branch
3124 build :
3225 runs-on : ubuntu-latest
3326 steps :
@@ -52,194 +45,29 @@ jobs:
5245 chmod +x scripts/install-tools.sh
5346 ./scripts/install-tools.sh
5447
55- # For PRs: Build with base path for preview subdirectory
56- - name : Build with mdBook (PR Preview)
57- if : github.event_name == 'pull_request'
58- run : |
59- # Update book.toml to use PR-specific path
60- sed -i 's|site-url = "/better-code/"|site-url = "/better-code/pr-preview/${{ github.event.number }}/"|' better-code/book.toml
61- mdbook build ./better-code
62-
63- # For main: Build with production path
64- - name : Build with mdBook (Production)
65- if : github.event_name == 'push' && github.ref == 'refs/heads/main'
48+ - name : Build with mdBook
6649 run : mdbook build ./better-code
67-
68- # Upload build artifact for inspection/debugging
69- - name : Upload build artifact
70- uses : actions/upload-artifact@v4
50+
51+ # Only deploy from main branch
52+ - name : Setup Pages
53+ if : github.ref == 'refs/heads/main'
54+ id : pages
55+ uses : actions/configure-pages@v5
56+
57+ - name : Upload artifact
58+ if : github.ref == 'refs/heads/main'
59+ uses : actions/upload-pages-artifact@v4
7160 with :
72- name : book-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || 'production' }}
7361 path : ./better-code/book
74- retention-days : ${{ github.event_name == 'pull_request' && 7 || 30 }}
75-
76- # PR Preview Deployment - deploys to gh-pages branch under pr-preview/NUMBER/
77- deploy-preview :
78- if : github.event_name == 'pull_request'
79- needs : build
80- runs-on : ubuntu-latest
81- steps :
82- - name : Checkout repository
83- uses : actions/checkout@v6
84- with :
85- fetch-depth : 0
86-
87- - name : Setup gh-pages branch
88- run : |
89- # Check if gh-pages branch exists
90- if git ls-remote --heads origin gh-pages | grep gh-pages; then
91- echo "gh-pages branch exists, checking out..."
92- git checkout gh-pages
93- else
94- echo "gh-pages branch doesn't exist, creating orphan branch..."
95- git checkout --orphan gh-pages
96- git rm -rf .
97- echo "# Better Code - PR Previews" > README.md
98- git add README.md
99- git config user.name "github-actions[bot]"
100- git config user.email "github-actions[bot]@users.noreply.github.com"
101- git commit -m "Initialize gh-pages branch for PR previews"
102- git push --set-upstream origin gh-pages
103- fi
104-
105- - name : Download build artifact
106- uses : actions/download-artifact@v4
107- with :
108- name : book-pr-${{ github.event.number }}
109- path : ./pr-preview/${{ github.event.number }}
110-
111- - name : Create preview index
112- run : |
113- # Create an index of all PR previews if it doesn't exist
114- if [ ! -f pr-preview/index.html ]; then
115- cat > pr-preview/index.html << 'EOF'
116- <!DOCTYPE html>
117- <html>
118- <head>
119- <title>PR Previews - Better Code</title>
120- <style>
121- body { font-family: system-ui; max-width: 800px; margin: 50px auto; padding: 20px; }
122- h1 { color: #333; }
123- ul { list-style: none; padding: 0; }
124- li { margin: 10px 0; padding: 10px; background: #f5f5f5; border-radius: 5px; }
125- a { color: #0066cc; text-decoration: none; }
126- a:hover { text-decoration: underline; }
127- </style>
128- </head>
129- <body>
130- <h1>Pull Request Previews</h1>
131- <p><a href="../">← Back to main documentation</a></p>
132- <p>Preview deployments for pull requests:</p>
133- <ul id="previews"></ul>
134- <script>
135- // List all PR preview directories
136- fetch('.')
137- .then(r => r.text())
138- .then(text => {
139- const parser = new DOMParser();
140- const doc = parser.parseFromString(text, 'text/html');
141- const links = Array.from(doc.querySelectorAll('a'))
142- .map(a => a.getAttribute('href'))
143- .filter(href => href && /^\d+\/$/.test(href))
144- .sort((a, b) => parseInt(b) - parseInt(a));
145-
146- const list = document.getElementById('previews');
147- if (links.length === 0) {
148- list.innerHTML = '<li>No active PR previews</li>';
149- } else {
150- links.forEach(link => {
151- const pr = link.replace('/', '');
152- const li = document.createElement('li');
153- li.innerHTML = `<a href="${link}">PR #${pr} Preview</a>`;
154- list.appendChild(li);
155- });
156- }
157- });
158- </script>
159- </body>
160- </html>
161- EOF
162- fi
163-
164- - name : Commit and push preview
165- run : |
166- git config user.name "github-actions[bot]"
167- git config user.email "github-actions[bot]@users.noreply.github.com"
168- git add pr-preview/${{ github.event.number }}
169- git add pr-preview/index.html
170- git commit -m "Deploy preview for PR #${{ github.event.number }}" || echo "No changes to commit"
171- git push
172-
173- - name : Comment PR with preview URL
174- uses : actions/github-script@v7
175- with :
176- script : |
177- const prNumber = context.issue.number;
178- const previewUrl = `https://stlab.github.io/better-code/pr-preview/${prNumber}/`;
179- const comment = `## 📚 Documentation Preview
180-
181- Your changes have been deployed to a preview environment:
182-
183- 🔗 **Preview URL:** ${previewUrl}
184-
185- This preview will be automatically updated with new commits and removed when the PR is closed.
186-
187- <sub>Built with commit ${context.sha.substring(0, 7)}</sub>`;
188-
189- // Find existing preview comment
190- const { data: comments } = await github.rest.issues.listComments({
191- owner: context.repo.owner,
192- repo: context.repo.repo,
193- issue_number: prNumber,
194- });
195-
196- const botComment = comments.find(comment =>
197- comment.user.type === 'Bot' &&
198- comment.body.includes('Documentation Preview')
199- );
200-
201- if (botComment) {
202- // Update existing comment
203- await github.rest.issues.updateComment({
204- owner: context.repo.owner,
205- repo: context.repo.repo,
206- comment_id: botComment.id,
207- body: comment
208- });
209- } else {
210- // Create new comment
211- await github.rest.issues.createComment({
212- owner: context.repo.owner,
213- repo: context.repo.repo,
214- issue_number: prNumber,
215- body: comment
216- });
217- }
21862
219- # Production Deployment - deploys to root of GitHub Pages
220- deploy-production :
221- if : github.event_name == 'push' && github.ref == 'refs/heads/main'
222- needs : build
63+ deploy :
64+ if : github.ref == 'refs/heads/main'
22365 environment :
22466 name : github-pages
22567 url : ${{ steps.deployment.outputs.page_url }}
22668 runs-on : ubuntu-latest
69+ needs : build
22770 steps :
228- - name : Download build artifact
229- uses : actions/download-artifact@v4
230- with :
231- name : book-production
232- path : ./book
233-
234- - name : Setup Pages
235- id : pages
236- uses : actions/configure-pages@v5
237-
238- - name : Upload Pages artifact
239- uses : actions/upload-pages-artifact@v4
240- with :
241- path : ./book
242-
24371 - name : Deploy to GitHub Pages
24472 id : deployment
24573 uses : actions/deploy-pages@v4
0 commit comments