-
Notifications
You must be signed in to change notification settings - Fork 73
Fix direct navigation 404 on Blazor sample pages #369
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d26c70d
8689ba1
a6c6551
fda9852
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -181,14 +181,19 @@ jobs: | |
| mkdir -p staging/$PR_NUMBER | ||
| rm -rf staging/$PR_NUMBER/* | ||
| cp -r /tmp/site-temp/. staging/$PR_NUMBER/ | ||
|
|
||
| # Copy 404.html to the gh-pages root so SPA redirects work for staging | ||
| # paths (GitHub Pages only serves the root-level 404.html for missing paths) | ||
| cp /tmp/site-temp/404.html 404.html | ||
|
|
||
| rm -rf /tmp/site-temp | ||
|
|
||
| # Ensure .nojekyll exists at root so _framework is served | ||
| touch .nojekyll | ||
|
|
||
| git config --local user.email "action@github.com" | ||
| git config --local user.name "GitHub Action" | ||
| git add .nojekyll staging/$PR_NUMBER | ||
| git add .nojekyll 404.html staging/$PR_NUMBER | ||
| if ! git diff --cached --quiet; then | ||
| git commit -m "Deploy staging docs for PR #$PR_NUMBER" | ||
| git push origin gh-pages | ||
|
|
@@ -199,7 +204,7 @@ jobs: | |
| comment: | ||
| runs-on: ubuntu-latest | ||
| needs: [build, deploy] | ||
| if: needs.build.outputs.is_staging == 'true' && (github.event.action == 'opened' || github.event.action == 'reopened') | ||
| if: needs.build.outputs.is_staging == 'true' && (github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'synchronize') | ||
| permissions: | ||
| pull-requests: write | ||
| steps: | ||
|
|
@@ -211,21 +216,6 @@ jobs: | |
| const stagingUrl = `https://mono.github.io/SkiaSharp.Extended/staging/${prNumber}/`; | ||
| const sampleUrl = `https://mono.github.io/SkiaSharp.Extended/staging/${prNumber}/sample/`; | ||
|
|
||
| // Only comment once; check for an existing bot comment to avoid duplicates on reopen | ||
| const comments = await github.rest.issues.listComments({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: prNumber | ||
| }); | ||
| const botComment = comments.data.find(c => | ||
| c.user.type === 'Bot' && | ||
| c.body.includes('Documentation Preview') | ||
| ); | ||
| if (botComment) { | ||
| console.log('Bot comment already exists, skipping.'); | ||
| return; | ||
| } | ||
|
|
||
| const commentBody = [ | ||
| '📖 **Documentation Preview**', | ||
| '', | ||
|
|
@@ -241,9 +231,28 @@ jobs: | |
| '*This comment is automatically updated by the documentation staging workflow.*' | ||
| ].join('\n'); | ||
|
|
||
| await github.rest.issues.createComment({ | ||
| // Update existing bot comment if present, otherwise create a new one | ||
| const comments = await github.rest.issues.listComments({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: prNumber, | ||
| body: commentBody | ||
| issue_number: prNumber | ||
| }); | ||
|
Comment on lines
+235
to
239
|
||
| const botComment = comments.data.find(c => | ||
| c.user.type === 'Bot' && | ||
| c.body.includes('Documentation Preview') | ||
| ); | ||
| if (botComment) { | ||
| await github.rest.issues.updateComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| comment_id: botComment.id, | ||
| body: commentBody | ||
| }); | ||
| } else { | ||
| await github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: prNumber, | ||
| body: commentBody | ||
| }); | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,33 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <!DOCTYPE html> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <html lang="en"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <head> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <meta charset="utf-8" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <title>SkiaSharp Extended - Page Not Found</title> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <script> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // GitHub Pages SPA redirect: when a user navigates directly to a Blazor sample | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // sub-page, GitHub Pages serves this 404.html. If the path is under a /sample/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // segment, redirect to that sample's index.html with the path encoded in the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // query string so that the Blazor router can restore the correct route. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (function () { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var l = window.location; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var pathParts = l.pathname.split('/'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var sampleIdx = pathParts.indexOf('sample'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (sampleIdx !== -1 && sampleIdx < pathParts.length - 1 && pathParts[sampleIdx + 1] !== '') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var basePath = pathParts.slice(0, sampleIdx + 1).join('/'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var remaining = pathParts.slice(sampleIdx + 1).join('/').replace(/&/g, '~and~'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| l.replace( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| basePath + '/?/' + remaining + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (l.search ? '&' + l.search.slice(1).replace(/&/g, '~and~') : '') + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| l.hash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </script> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </head> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <body> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <h1>Page Not Found</h1> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p>The page you are looking for does not exist.</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p><a href="/SkiaSharp.Extended/">Go to the documentation</a></p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+25
to
+31
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })(); | |
| </script> | |
| </head> | |
| <body> | |
| <h1>Page Not Found</h1> | |
| <p>The page you are looking for does not exist.</p> | |
| <p><a href="/SkiaSharp.Extended/">Go to the documentation</a></p> | |
| // Compute the base documentation path so the fallback link works on both | |
| // the main site (/SkiaSharp.Extended/...) and staging URLs | |
| // (/SkiaSharp.Extended/staging/<pr>/...). | |
| function getDocsBasePath() { | |
| var parts = l.pathname.split('/'); | |
| var extendedIndex = parts.indexOf('SkiaSharp.Extended'); | |
| if (extendedIndex === -1) { | |
| // Fallback if the expected segment is not present. | |
| return '/'; | |
| } | |
| // Start with /SkiaSharp.Extended/ | |
| var endIndex = extendedIndex + 2; // include 'SkiaSharp.Extended' | |
| // If this is a staging URL like /SkiaSharp.Extended/staging/<pr>/..., | |
| // include the staging and PR segments as part of the base path. | |
| if (parts[extendedIndex + 1] === 'staging' && parts.length > extendedIndex + 2) { | |
| endIndex = extendedIndex + 3; | |
| } | |
| var base = parts.slice(0, endIndex).join('/'); | |
| if (base === '') { | |
| base = '/'; | |
| } | |
| // Ensure a trailing slash for consistency. | |
| if (base.charAt(base.length - 1) !== '/') { | |
| base += '/'; | |
| } | |
| return base; | |
| } | |
| window.addEventListener('DOMContentLoaded', function () { | |
| var link = document.getElementById('docs-link'); | |
| if (!link) { | |
| return; | |
| } | |
| link.href = getDocsBasePath(); | |
| }); | |
| })(); | |
| </script> | |
| </head> | |
| <body> | |
| <h1>Page Not Found</h1> | |
| <p>The page you are looking for does not exist.</p> | |
| <p><a id="docs-link" href="#">Go to the documentation</a></p> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,7 +30,8 @@ | |
| "resource": [ | ||
| { | ||
| "files": [ | ||
| "images/**" | ||
| "images/**", | ||
| "404.html" | ||
| ] | ||
| } | ||
| ], | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The staging deploy step copies the built
404.htmlinto the gh-pages root. This means every staging deployment can overwrite the root 404 used by the main docs site, temporarily changing production 404 behavior until the next main deploy. Consider avoiding mutating the root 404 on staging runs (or only doing it when the staged 404 is identical to the current root file), so staging previews don't affect the main site.