From a9b64c66052a949159ffa922a7f3a83c093ee631 Mon Sep 17 00:00:00 2001
From: ampelectrecuted <197376797+ampelectrecuted@users.noreply.github.com>
Date: Tue, 7 Oct 2025 20:10:01 +0100
Subject: [PATCH 01/43] will this work
---
.github/workflows/prtest.yml | 50 +++++++++++++++++++-----------------
1 file changed, 26 insertions(+), 24 deletions(-)
diff --git a/.github/workflows/prtest.yml b/.github/workflows/prtest.yml
index d35618aaa..d3ad5a1f8 100644
--- a/.github/workflows/prtest.yml
+++ b/.github/workflows/prtest.yml
@@ -7,7 +7,7 @@ on:
types: [opened]
permissions:
- contents: write
+ contents: read
pull-requests: write
pages: write
id-token: write
@@ -18,7 +18,11 @@ jobs:
(github.event_name == 'pull_request' && github.event.action == 'opened') ||
(github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '/test pr'))
runs-on: ubuntu-latest
-
+
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+
steps:
- name: Record start time
id: start_time
@@ -48,7 +52,6 @@ jobs:
uses: actions/github-script@v7
with:
script: |
- // FIXED: Use context.eventName and context.payload
const username = context.eventName === 'issue_comment'
? context.payload.comment.user.login
: context.payload.pull_request.user.login;
@@ -60,9 +63,7 @@ jobs:
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
- body: `šØ **Building PR for testing...** (requested by @${username}) š§\n\n` +
- `` +
- `šļø Please wait while the build completes. This may take a few minutes. āļø`
+ body: `šØ **Building PR for testing...** (requested by @${username}) š§`
});
return comment.data.id;
@@ -71,7 +72,6 @@ jobs:
uses: actions/github-script@v7
with:
script: |
- // FIXED: Use context.eventName and context.payload
const prNumber = context.eventName === 'issue_comment'
? context.issue.number
: context.payload.number;
@@ -107,17 +107,20 @@ jobs:
env:
NODE_ENV: production
- - name: Add .nojekyll file
- run: touch build/.nojekyll
+ - name: Prepare per-PR directory
+ run: |
+ mkdir -p ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}
+ cp -r ./build/* ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}/
+ touch ./public/.nojekyll
+
+ - name: Upload Pages artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./public
- name: Deploy to GitHub Pages
- uses: peaceiris/actions-gh-pages@v3
- with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- publish_dir: ./build
- publish_branch: gh-pages
- force_orphan: true
- commit_message: '[PR Test] Deploy PR #${{ fromJSON(steps.pr.outputs.result).number }} (${{ fromJSON(steps.pr.outputs.result).sha }})'
+ id: deployment
+ uses: actions/deploy-pages@v4
- name: Calculate duration
id: duration
@@ -135,7 +138,6 @@ jobs:
uses: actions/github-script@v7
with:
script: |
- // FIXED: Use context.eventName and context.payload
const prNumber = ${{ fromJSON(steps.pr.outputs.result).number }};
const sha = '${{ fromJSON(steps.pr.outputs.result).sha }}'.substring(0, 7);
const commentId = ${{ steps.build_comment.outputs.result }};
@@ -143,20 +145,21 @@ jobs:
? context.payload.comment.user.login
: context.payload.pull_request.user.login;
const duration = '${{ steps.duration.outputs.duration }}';
+ const pageUrl = '${{ steps.deployment.outputs.page_url }}';
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: commentId,
body: `š **PR Test Deployment Complete!**\n\n` +
- `Hi, @${username}! Your pull request test deployment is complete! ā
š\n\n` +
- `View your changes at: https://omniblocks.github.io/scratch-gui\n\n` +
+ `Hi, @${username}! Your PR test deployment is ready! ā
š\n\n` +
+ `š View it here:\n` +
+ `${pageUrl}${username}/${prNumber}/\n\n` +
`**Details:**\n` +
`- PR: #${prNumber}\n` +
`- Commit: \`${sha}\`\n` +
`- Requested by: @${username}\n` +
- `- Build time: ${duration}\n` +
- `- Note: This deployment will be replaced when another PR is tested.`
+ `- Build time: ${duration}\n`
});
- name: Update comment with failure
@@ -164,7 +167,6 @@ jobs:
uses: actions/github-script@v7
with:
script: |
- // FIXED: Use context.eventName and context.payload
const commentId = ${{ steps.build_comment.outputs.result }};
const username = context.eventName === 'issue_comment'
? context.payload.comment.user.login
@@ -176,7 +178,7 @@ jobs:
repo: context.repo.repo,
comment_id: commentId,
body: `ā **PR Test Deployment Failed** @${username}\n\n` +
- `Something went wrong during the build or deployment process.\n` +
+ `Something went wrong during build or deployment.\n` +
`Build time: ${duration}\n\n` +
- `Check the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.`
+ `Check logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`
});
From 4cb1a103b18162082cc7410abc672ac46ebe5cc7 Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Tue, 7 Oct 2025 15:18:14 -0400
Subject: [PATCH 02/43] Update prtest.yml
---
.github/workflows/prtest.yml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/prtest.yml b/.github/workflows/prtest.yml
index d3ad5a1f8..77c37c0ae 100644
--- a/.github/workflows/prtest.yml
+++ b/.github/workflows/prtest.yml
@@ -63,7 +63,9 @@ jobs:
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
- body: `šØ **Building PR for testing...** (requested by @${username}) š§`
+ body: `šØ **Building PR for testing...** (requested by @${username}) š§\n\n` +
+ `
` +
+ `šļø Please wait while the build completes. This may take a few minutes. āļø`
});
return comment.data.id;
From fb792235b993720cb7a3e635854663779efc6b0d Mon Sep 17 00:00:00 2001
From: ampelectrecuted <197376797+ampelectrecuted@users.noreply.github.com>
Date: Tue, 7 Oct 2025 20:35:49 +0100
Subject: [PATCH 03/43] new cache epoch
---
webpack.config.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/webpack.config.js b/webpack.config.js
index 96c30a17c..930bd0c16 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -29,7 +29,7 @@ const htmlWebpackPluginCommon = {
};
// When this changes, the path for all JS files will change, bypassing any HTTP caches
-const CACHE_EPOCH = 'pentapod';
+const CACHE_EPOCH = 'omnibruh';
const base = {
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
From f2382300e64b082136c8cff26a75f076ab627e3d Mon Sep 17 00:00:00 2001
From: ampelectrecuted <197376797+ampelectrecuted@users.noreply.github.com>
Date: Tue, 7 Oct 2025 20:41:01 +0100
Subject: [PATCH 04/43] speed up with cache
---
webpack.config.js | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/webpack.config.js b/webpack.config.js
index 930bd0c16..2e413ea10 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -69,6 +69,9 @@ const base = {
'scratch-render-fonts$': path.resolve(__dirname, 'src/lib/tw-scratch-render-fonts')
}
},
+ cache: {
+ type: 'filesystem',
+ },
module: {
rules: [{
test: /\.jsx?$/,
@@ -87,7 +90,8 @@ const base = {
['react-intl', {
messagesDir: './translations/messages/'
}]],
- presets: ['@babel/preset-env', '@babel/preset-react']
+ presets: ['@babel/preset-env', '@babel/preset-react'],
+ cacheDirectory: true,
}
},
{
@@ -140,7 +144,7 @@ const base = {
if (!process.env.CI) {
base.plugins.push(new webpack.ProgressPlugin());
- base.plugins.push(new webpack.HotModuleReplacementPlugin());
+ base.plugins.push(new webpack.HotModuleReplacementPlugin());
}
module.exports = [
From 9b1f7fabb5953a096be6eef9157ab559d65426d8 Mon Sep 17 00:00:00 2001
From: ampelectrecuted <197376797+ampelectrecuted@users.noreply.github.com>
Date: Tue, 7 Oct 2025 20:41:16 +0100
Subject: [PATCH 05/43] remove debug
---
webpack.config.js | 3 ---
1 file changed, 3 deletions(-)
diff --git a/webpack.config.js b/webpack.config.js
index 2e413ea10..23c8f4bfe 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -13,9 +13,6 @@ const postcssImport = require('postcss-import');
const STATIC_PATH = process.env.STATIC_PATH || '/static';
const {APP_NAME} = require('./src/lib/brand');
-console.log('š DEBUG: Webpack config loading...');
-console.log('š DEBUG: APP_VERSION from env:', process.env.APP_VERSION);
-console.log('š DEBUG: Will inject:', JSON.stringify(process.env.APP_VERSION || ''));
const root = process.env.ROOT || '';
if (root.length > 0 && !root.endsWith('/')) {
From d4fc8b0a157669809b132be8cd95665734dadbf6 Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Tue, 7 Oct 2025 15:47:21 -0400
Subject: [PATCH 06/43] Update webpack.config.js
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---
webpack.config.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/webpack.config.js b/webpack.config.js
index 23c8f4bfe..8855bfa32 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -68,6 +68,9 @@ const base = {
},
cache: {
type: 'filesystem',
+ buildDependencies: {
+ config: [__filename]
+ }
},
module: {
rules: [{
From 237aef842e7b96991f2fc31c370efa3df63056cc Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Tue, 7 Oct 2025 16:03:50 -0400
Subject: [PATCH 07/43] Update prtest.yml
---
.github/workflows/prtest.yml | 121 +++++++++++++++++++++++++++++------
1 file changed, 100 insertions(+), 21 deletions(-)
diff --git a/.github/workflows/prtest.yml b/.github/workflows/prtest.yml
index 77c37c0ae..e1ea97e81 100644
--- a/.github/workflows/prtest.yml
+++ b/.github/workflows/prtest.yml
@@ -46,28 +46,107 @@ jobs:
comment_id: context.payload.comment.id,
content: 'rocket'
});
+# Replace the existing "Post building comment" section with this:
- - name: Post building comment
- id: build_comment
- uses: actions/github-script@v7
- with:
- script: |
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- const issueNumber = context.eventName === 'issue_comment'
- ? context.issue.number
- : context.payload.number;
-
- const comment = await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: issueNumber,
- body: `šØ **Building PR for testing...** (requested by @${username}) š§\n\n` +
- `
` +
- `šļø Please wait while the build completes. This may take a few minutes. āļø`
- });
- return comment.data.id;
+- name: Post building comment
+ id: build_comment
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const spinner = '
';
+ const comment = await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: ${{ fromJSON(steps.pr.outputs.result).number }},
+ body: `${spinner} **Building PR for testing...**\n\n` +
+ `${spinner} Checkout & Setup\n` +
+ `⬠Installing dependencies\n` +
+ `⬠Building\n` +
+ `⬠Deploying`
+ });
+ return comment.data.id;
+
+- name: Update comment - Installing Dependencies
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const spinner = '
';
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${spinner} **Building PR for testing...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `${spinner} Installing dependencies\n` +
+ `⬠Building\n` +
+ `⬠Deploying`
+ });
+
+- name: Install dependencies
+ run: npm ci
+
+- name: Update comment - Building
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const spinner = '
';
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${spinner} **Building PR for testing...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `ā
Installing dependencies\n` +
+ `${spinner} Building\n` +
+ `⬠Deploying`
+ });
+
+- name: Build website
+ run: npm run build
+ env:
+ NODE_ENV: production
+
+- name: Update comment - Deploying
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const spinner = '
';
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${spinner} **Building PR for testing...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `ā
Installing dependencies\n` +
+ `ā
Building\n` +
+ `${spinner} Deploying to GitHub Pages`
+ });
+
+- name: Prepare per-PR directory
+ run: |
+ # ... (your existing preparation code)
+
+- name: Update comment - Deployment Complete
+ if: success()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const pageUrl = '${{ steps.deployment.outputs.page_url }}';
+ const username = '${{ github.actor }}';
+ const prNumber = ${{ fromJSON(steps.pr.outputs.result).number }};
+ const duration = ((Date.now() - ${{ steps.start_time.outputs.timestamp }}) / 1000).toFixed(0);
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `ā
**PR test build deployed!**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `ā
Installing dependencies\n` +
+ `ā
Building\n` +
+ `ā
Deploying to GitHub Pages\n\n` +
+ `š **Preview URL:** ${pageUrl}${username}/${prNumber}/\n` +
+ `ā±ļø Build time: ${duration}s`
+ });
- name: Get PR details
id: pr
From 46358f7590099fc1a898a90ba23ab1a30c4fc8fc Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Tue, 7 Oct 2025 16:54:23 -0400
Subject: [PATCH 08/43] Update prtest.yml
---
.github/workflows/prtest.yml | 171 ++++++++++++++---------------------
1 file changed, 68 insertions(+), 103 deletions(-)
diff --git a/.github/workflows/prtest.yml b/.github/workflows/prtest.yml
index e1ea97e81..b42cef8ff 100644
--- a/.github/workflows/prtest.yml
+++ b/.github/workflows/prtest.yml
@@ -46,107 +46,6 @@ jobs:
comment_id: context.payload.comment.id,
content: 'rocket'
});
-# Replace the existing "Post building comment" section with this:
-
-- name: Post building comment
- id: build_comment
- uses: actions/github-script@v7
- with:
- script: |
- const spinner = '
';
- const comment = await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: ${{ fromJSON(steps.pr.outputs.result).number }},
- body: `${spinner} **Building PR for testing...**\n\n` +
- `${spinner} Checkout & Setup\n` +
- `⬠Installing dependencies\n` +
- `⬠Building\n` +
- `⬠Deploying`
- });
- return comment.data.id;
-
-- name: Update comment - Installing Dependencies
- uses: actions/github-script@v7
- with:
- script: |
- const spinner = '
';
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${spinner} **Building PR for testing...**\n\n` +
- `ā
Checkout & Setup\n` +
- `${spinner} Installing dependencies\n` +
- `⬠Building\n` +
- `⬠Deploying`
- });
-
-- name: Install dependencies
- run: npm ci
-
-- name: Update comment - Building
- uses: actions/github-script@v7
- with:
- script: |
- const spinner = '
';
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${spinner} **Building PR for testing...**\n\n` +
- `ā
Checkout & Setup\n` +
- `ā
Installing dependencies\n` +
- `${spinner} Building\n` +
- `⬠Deploying`
- });
-
-- name: Build website
- run: npm run build
- env:
- NODE_ENV: production
-
-- name: Update comment - Deploying
- uses: actions/github-script@v7
- with:
- script: |
- const spinner = '
';
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${spinner} **Building PR for testing...**\n\n` +
- `ā
Checkout & Setup\n` +
- `ā
Installing dependencies\n` +
- `ā
Building\n` +
- `${spinner} Deploying to GitHub Pages`
- });
-
-- name: Prepare per-PR directory
- run: |
- # ... (your existing preparation code)
-
-- name: Update comment - Deployment Complete
- if: success()
- uses: actions/github-script@v7
- with:
- script: |
- const pageUrl = '${{ steps.deployment.outputs.page_url }}';
- const username = '${{ github.actor }}';
- const prNumber = ${{ fromJSON(steps.pr.outputs.result).number }};
- const duration = ((Date.now() - ${{ steps.start_time.outputs.timestamp }}) / 1000).toFixed(0);
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `ā
**PR test build deployed!**\n\n` +
- `ā
Checkout & Setup\n` +
- `ā
Installing dependencies\n` +
- `ā
Building\n` +
- `ā
Deploying to GitHub Pages\n\n` +
- `š **Preview URL:** ${pageUrl}${username}/${prNumber}/\n` +
- `ā±ļø Build time: ${duration}s`
- });
- name: Get PR details
id: pr
@@ -156,7 +55,7 @@ jobs:
const prNumber = context.eventName === 'issue_comment'
? context.issue.number
: context.payload.number;
-
+
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
@@ -168,6 +67,24 @@ jobs:
number: pr.data.number
};
+ - name: Post building comment
+ id: build_comment
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const spinner = '
';
+ const comment = await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: ${{ fromJSON(steps.pr.outputs.result).number }},
+ body: `${spinner} **Building PR for testing...**\n\n` +
+ `${spinner} Checkout & Setup\n` +
+ `⬠Installing dependencies\n` +
+ `⬠Building\n` +
+ `⬠Deploying`
+ });
+ return comment.data.id;
+
- name: Checkout PR code
uses: actions/checkout@v4
with:
@@ -180,14 +97,62 @@ jobs:
node-version: '20'
cache: 'npm'
+ - name: Update comment - Installing Dependencies
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const spinner = '
';
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${spinner} **Building PR for testing...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `${spinner} Installing dependencies\n` +
+ `⬠Building\n` +
+ `⬠Deploying`
+ });
+
- name: Install dependencies
run: npm ci
+ - name: Update comment - Building
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const spinner = '
';
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${spinner} **Building PR for testing...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `ā
Installing dependencies\n` +
+ `${spinner} Building\n` +
+ `⬠Deploying`
+ });
+
- name: Build website
run: npm run build
env:
NODE_ENV: production
+ - name: Update comment - Deploying
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const spinner = '
';
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${spinner} **Building PR for testing...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `ā
Installing dependencies\n` +
+ `ā
Building\n` +
+ `${spinner} Deploying to GitHub Pages`
+ });
+
- name: Prepare per-PR directory
run: |
mkdir -p ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}
@@ -227,7 +192,7 @@ jobs:
: context.payload.pull_request.user.login;
const duration = '${{ steps.duration.outputs.duration }}';
const pageUrl = '${{ steps.deployment.outputs.page_url }}';
-
+
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
From 709dce41f5f30558b90e7d79e2aa63b2ff711de8 Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Tue, 7 Oct 2025 17:42:35 -0400
Subject: [PATCH 09/43] Update prtest.yml
---
.github/workflows/prtest.yml | 66 +++++++++++++++++++++++++++++++-----
1 file changed, 58 insertions(+), 8 deletions(-)
diff --git a/.github/workflows/prtest.yml b/.github/workflows/prtest.yml
index b42cef8ff..6fceb659b 100644
--- a/.github/workflows/prtest.yml
+++ b/.github/workflows/prtest.yml
@@ -72,12 +72,15 @@ jobs:
uses: actions/github-script@v7
with:
script: |
- const spinner = '
';
+ const spinner = '
';
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
const comment = await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: ${{ fromJSON(steps.pr.outputs.result).number }},
- body: `${spinner} **Building PR for testing...**\n\n` +
+ body: `${spinner} **Building PR for testing, requested by @${username}...**\n\n` +
`${spinner} Checkout & Setup\n` +
`⬠Installing dependencies\n` +
`⬠Building\n` +
@@ -101,12 +104,15 @@ jobs:
uses: actions/github-script@v7
with:
script: |
- const spinner = '
';
+ const spinner = '
';
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${spinner} **Building PR for testing...**\n\n` +
+ body: `${spinner} **Building PR for testing, requested by @${username}...**\n\n` +
`ā
Checkout & Setup\n` +
`${spinner} Installing dependencies\n` +
`⬠Building\n` +
@@ -120,12 +126,15 @@ jobs:
uses: actions/github-script@v7
with:
script: |
- const spinner = '
';
+ const spinner = '
';
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${spinner} **Building PR for testing...**\n\n` +
+ body: `${spinner} **Building PR for testing, requested by @${username}...**\n\n` +
`ā
Checkout & Setup\n` +
`ā
Installing dependencies\n` +
`${spinner} Building\n` +
@@ -141,12 +150,15 @@ jobs:
uses: actions/github-script@v7
with:
script: |
- const spinner = '
';
+ const spinner = '
';
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${spinner} **Building PR for testing...**\n\n` +
+ body: `${spinner} **Building PR for testing, requested by @${username}...**\n\n` +
`ā
Checkout & Setup\n` +
`ā
Installing dependencies\n` +
`ā
Building\n` +
@@ -228,3 +240,41 @@ jobs:
`Build time: ${duration}\n\n` +
`Check logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`
});
+ const duration = '${{ steps.duration.outputs.duration }}';
+ const pageUrl = '${{ steps.deployment.outputs.page_url }}';
+
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: commentId,
+ body: `š **PR Test Deployment Complete!**\n\n` +
+ `Hi, @${username}! Your PR test deployment is ready! ā
š\n\n` +
+ `š View it here:\n` +
+ `${pageUrl}${username}/${prNumber}/\n\n` +
+ `**Details:**\n` +
+ `- PR: #${prNumber}\n` +
+ `- Commit: \`${sha}\`\n` +
+ `- Requested by: @${username}\n` +
+ `- Build time: ${duration}\n`
+ });
+
+ - name: Update comment with failure
+ if: failure()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const commentId = ${{ steps.build_comment.outputs.result }};
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ const duration = '${{ steps.duration.outputs.duration }}';
+
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: commentId,
+ body: `ā **PR Test Deployment Failed** @${username}\n\n` +
+ `Something went wrong during build or deployment.\n` +
+ `Build time: ${duration}\n\n` +
+ `Check logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`
+ });
From 5c4340714dbdcca7fe7d8e0b0cbb3ccec2620724 Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Tue, 7 Oct 2025 18:00:48 -0400
Subject: [PATCH 10/43] Update prtest.yml
---
.github/workflows/prtest.yml | 140 ++++++++++++++++++++++++++++++++++-
1 file changed, 136 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/prtest.yml b/.github/workflows/prtest.yml
index 6fceb659b..29cac3094 100644
--- a/.github/workflows/prtest.yml
+++ b/.github/workflows/prtest.yml
@@ -72,7 +72,8 @@ jobs:
uses: actions/github-script@v7
with:
script: |
- const spinner = '
';
+ const initial_spinner = '
';
+ const checklist_spinner = '
';
const username = context.eventName === 'issue_comment'
? context.payload.comment.user.login
: context.payload.pull_request.user.login;
@@ -80,8 +81,8 @@ jobs:
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: ${{ fromJSON(steps.pr.outputs.result).number }},
- body: `${spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `${spinner} Checkout & Setup\n` +
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `${checklist_spinner} Checkout & Setup\n` +
`⬠Installing dependencies\n` +
`⬠Building\n` +
`⬠Deploying`
@@ -104,7 +105,56 @@ jobs:
uses: actions/github-script@v7
with:
script: |
- const spinner = '
';
+ const initial_spinner = '
';
+ const checklist_spinner = '
';
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `${checklist_spinner} Installing dependencies\n` +
+ `⬠Building\n` +
+ `⬠Deploying`
+ });
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Update comment - Building
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const initial_spinner = '
';
+ const checklist_spinner = '
';
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `ā
Installing dependencies\n` +
+ `${checklist_spinner} Building\n` +
+ `⬠Deploying`
+ });
+
+ - name: Build website
+ run: npm run build
+ env:
+ NODE_ENV: production
+
+ - name: Update comment - Deploying
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const initial_spinner = '
';
+ const checklist_spinner = '
';
const username = context.eventName === 'issue_comment'
? context.payload.comment.user.login
: context.payload.pull_request.user.login;
@@ -112,6 +162,88 @@ jobs:
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `ā
Installing dependencies\n` +
+ `ā
Building\n` +
+ `${checklist_spinner} Deploying to GitHub Pages`
+ });
+
+ - name: Prepare per-PR directory
+ run: |
+ mkdir -p ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}
+ cp -r ./build/* ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}/
+ touch ./public/.nojekyll
+
+ - name: Upload Pages artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./public
+
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
+
+ - name: Calculate duration
+ id: duration
+ if: always()
+ run: |
+ END_TIME=$(date +%s)
+ START_TIME=${{ steps.start_time.outputs.timestamp }}
+ DURATION=$((END_TIME - START_TIME))
+ MINUTES=$((DURATION / 60))
+ SECONDS=$((DURATION % 60))
+ echo "duration=${MINUTES}m ${SECONDS}s" >> $GITHUB_OUTPUT
+
+ - name: Update comment with success
+ if: success()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const prNumber = ${{ fromJSON(steps.pr.outputs.result).number }};
+ const sha = '${{ fromJSON(steps.pr.outputs.result).sha }}'.substring(0, 7);
+ const commentId = ${{ steps.build_comment.outputs.result }};
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ const duration = '${{ steps.duration.outputs.duration }}';
+ const pageUrl = '${{ steps.deployment.outputs.page_url }}';
+
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: commentId,
+ body: `š **PR Test Deployment Complete!**\n\n` +
+ `Hi, @${username}! Your PR test deployment is ready! ā
š\n\n` +
+ `š View it here:\n` +
+ `${pageUrl}${username}/${prNumber}/\n\n` +
+ `**Details:**\n` +
+ `- PR: #${prNumber}\n` +
+ `- Commit: \`${sha}\`\n` +
+ `- Requested by: @${username}\n` +
+ `- Build time: ${duration}\n`
+ });
+
+ - name: Update comment with failure
+ if: failure()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const commentId = ${{ steps.build_comment.outputs.result }};
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ const duration = '${{ steps.duration.outputs.duration }}';
+
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: commentId,
+ body: `ā **PR Test Deployment Failed** @${username}\n\n` +
+ `Something went wrong during build or deployment.\n` +
+ `Build time: ${duration}\n\n` +
+ `Check logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`
+ });
body: `${spinner} **Building PR for testing, requested by @${username}...**\n\n` +
`ā
Checkout & Setup\n` +
`${spinner} Installing dependencies\n` +
From 668f2fc2dfcdd3f49104460e96f6b98bf6a46361 Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Tue, 7 Oct 2025 19:52:59 -0400
Subject: [PATCH 11/43] Update prtest.yml
---
.github/workflows/prtest.yml | 132 +++++++++++++++++++++++++++++++++++
1 file changed, 132 insertions(+)
diff --git a/.github/workflows/prtest.yml b/.github/workflows/prtest.yml
index 29cac3094..800d797e1 100644
--- a/.github/workflows/prtest.yml
+++ b/.github/workflows/prtest.yml
@@ -224,6 +224,138 @@ jobs:
`- Build time: ${duration}\n`
});
+ - name: Update comment with failure
+ if: failure()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const commentId = ${{ steps.build_comment.outputs.result }};
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ const duration = '${{ steps.duration.outputs.duration }}';
+
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: commentId,
+ body: `ā **PR Test Deployment Failed** @${username}\n\n` +
+ `Something went wrong during build or deployment.\n` +
+ `Build time: ${duration}\n\n` +
+ `Check logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`
+ });
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `${checklist_spinner} Installing dependencies\n` +
+ `⬠Building\n` +
+ `⬠Deploying`
+ });
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Update comment - Building
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const initial_spinner = '
';
+ const checklist_spinner = '
';
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `ā
Installing dependencies\n` +
+ `${checklist_spinner} Building\n` +
+ `⬠Deploying`
+ });
+
+ - name: Build website
+ run: npm run build
+ env:
+ NODE_ENV: production
+
+ - name: Update comment - Deploying
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const initial_spinner = '
';
+ const checklist_spinner = '
';
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `ā
Installing dependencies\n` +
+ `ā
Building\n` +
+ `${checklist_spinner} Deploying to GitHub Pages`
+ });
+
+ - name: Prepare per-PR directory
+ run: |
+ mkdir -p ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}
+ cp -r ./build/* ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}/
+ touch ./public/.nojekyll
+
+ - name: Upload Pages artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./public
+
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
+
+ - name: Calculate duration
+ id: duration
+ if: always()
+ run: |
+ END_TIME=$(date +%s)
+ START_TIME=${{ steps.start_time.outputs.timestamp }}
+ DURATION=$((END_TIME - START_TIME))
+ MINUTES=$((DURATION / 60))
+ SECONDS=$((DURATION % 60))
+ echo "duration=${MINUTES}m ${SECONDS}s" >> $GITHUB_OUTPUT
+
+ - name: Update comment with success
+ if: success()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const prNumber = ${{ fromJSON(steps.pr.outputs.result).number }};
+ const sha = '${{ fromJSON(steps.pr.outputs.result).sha }}'.substring(0, 7);
+ const commentId = ${{ steps.build_comment.outputs.result }};
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ const duration = '${{ steps.duration.outputs.duration }}';
+ const pageUrl = '${{ steps.deployment.outputs.page_url }}';
+
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: commentId,
+ body: `š **PR Test Deployment Complete!**\n\n` +
+ `Hi, @${username}! Your PR test deployment is ready! ā
š\n\n` +
+ `š View it here:\n` +
+ `${pageUrl}${username}/${prNumber}/\n\n` +
+ `**Details:**\n` +
+ `- PR: #${prNumber}\n` +
+ `- Commit: \`${sha}\`\n` +
+ `- Requested by: @${username}\n` +
+ `- Build time: ${duration}\n`
+ });
+
- name: Update comment with failure
if: failure()
uses: actions/github-script@v7
From 9b155576df4674ed0f793e58806f2ec18883e867 Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Tue, 7 Oct 2025 19:55:51 -0400
Subject: [PATCH 12/43] Update prtest.yml
---
.github/workflows/prtest.yml | 132 +++++++++++++++++++++++++++++++++++
1 file changed, 132 insertions(+)
diff --git a/.github/workflows/prtest.yml b/.github/workflows/prtest.yml
index 800d797e1..ea2728903 100644
--- a/.github/workflows/prtest.yml
+++ b/.github/workflows/prtest.yml
@@ -356,6 +356,138 @@ jobs:
`- Build time: ${duration}\n`
});
+ - name: Update comment with failure
+ if: failure()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const commentId = ${{ steps.build_comment.outputs.result }};
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ const duration = '${{ steps.duration.outputs.duration }}';
+
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: commentId,
+ body: `ā **PR Test Deployment Failed** @${username}\n\n` +
+ `Something went wrong during build or deployment.\n` +
+ `Build time: ${duration}\n\n` +
+ `Check logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`
+ });
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `${checklist_spinner} Installing dependencies\n` +
+ `⬠Building\n` +
+ `⬠Deploying`
+ });
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Update comment - Building
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const initial_spinner = '
';
+ const checklist_spinner = '
';
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `ā
Installing dependencies\n` +
+ `${checklist_spinner} Building\n` +
+ `⬠Deploying`
+ });
+
+ - name: Build website
+ run: npm run build
+ env:
+ NODE_ENV: production
+
+ - name: Update comment - Deploying
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const initial_spinner = '
';
+ const checklist_spinner = '
';
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `ā
Installing dependencies\n` +
+ `ā
Building\n` +
+ `${checklist_spinner} Deploying to GitHub Pages`
+ });
+
+ - name: Prepare per-PR directory
+ run: |
+ mkdir -p ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}
+ cp -r ./build/* ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}/
+ touch ./public/.nojekyll
+
+ - name: Upload Pages artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./public
+
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
+
+ - name: Calculate duration
+ id: duration
+ if: always()
+ run: |
+ END_TIME=$(date +%s)
+ START_TIME=${{ steps.start_time.outputs.timestamp }}
+ DURATION=$((END_TIME - START_TIME))
+ MINUTES=$((DURATION / 60))
+ SECONDS=$((DURATION % 60))
+ echo "duration=${MINUTES}m ${SECONDS}s" >> $GITHUB_OUTPUT
+
+ - name: Update comment with success
+ if: success()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const prNumber = ${{ fromJSON(steps.pr.outputs.result).number }};
+ const sha = '${{ fromJSON(steps.pr.outputs.result).sha }}'.substring(0, 7);
+ const commentId = ${{ steps.build_comment.outputs.result }};
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ const duration = '${{ steps.duration.outputs.duration }}';
+ const pageUrl = '${{ steps.deployment.outputs.page_url }}';
+
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: commentId,
+ body: `š **PR Test Deployment Complete!**\n\n` +
+ `Hi, @${username}! Your PR test deployment is ready! ā
š\n\n` +
+ `š View it here:\n` +
+ `${pageUrl}${username}/${prNumber}/\n\n` +
+ `**Details:**\n` +
+ `- PR: #${prNumber}\n` +
+ `- Commit: \`${sha}\`\n` +
+ `- Requested by: @${username}\n` +
+ `- Build time: ${duration}\n`
+ });
+
- name: Update comment with failure
if: failure()
uses: actions/github-script@v7
From 05c676ede15fa7d616d1bd0f7b0b86dff5f2f0d6 Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Tue, 7 Oct 2025 20:06:52 -0400
Subject: [PATCH 13/43] Update prtest.yml
---
.github/workflows/prtest.yml | 432 +----------------------------------
1 file changed, 2 insertions(+), 430 deletions(-)
diff --git a/.github/workflows/prtest.yml b/.github/workflows/prtest.yml
index ea2728903..bae437b28 100644
--- a/.github/workflows/prtest.yml
+++ b/.github/workflows/prtest.yml
@@ -72,7 +72,9 @@ jobs:
uses: actions/github-script@v7
with:
script: |
+ // Spinner for the main message (original larger one)
const initial_spinner = '
';
+ // Spinner for checklist items (new smaller one)
const checklist_spinner = '
';
const username = context.eventName === 'issue_comment'
? context.payload.comment.user.login
@@ -244,433 +246,3 @@ jobs:
`Build time: ${duration}\n\n` +
`Check logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`
});
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `ā
Checkout & Setup\n` +
- `${checklist_spinner} Installing dependencies\n` +
- `⬠Building\n` +
- `⬠Deploying`
- });
-
- - name: Install dependencies
- run: npm ci
-
- - name: Update comment - Building
- uses: actions/github-script@v7
- with:
- script: |
- const initial_spinner = '
';
- const checklist_spinner = '
';
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `ā
Checkout & Setup\n` +
- `ā
Installing dependencies\n` +
- `${checklist_spinner} Building\n` +
- `⬠Deploying`
- });
-
- - name: Build website
- run: npm run build
- env:
- NODE_ENV: production
-
- - name: Update comment - Deploying
- uses: actions/github-script@v7
- with:
- script: |
- const initial_spinner = '
';
- const checklist_spinner = '
';
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `ā
Checkout & Setup\n` +
- `ā
Installing dependencies\n` +
- `ā
Building\n` +
- `${checklist_spinner} Deploying to GitHub Pages`
- });
-
- - name: Prepare per-PR directory
- run: |
- mkdir -p ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}
- cp -r ./build/* ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}/
- touch ./public/.nojekyll
-
- - name: Upload Pages artifact
- uses: actions/upload-pages-artifact@v3
- with:
- path: ./public
-
- - name: Deploy to GitHub Pages
- id: deployment
- uses: actions/deploy-pages@v4
-
- - name: Calculate duration
- id: duration
- if: always()
- run: |
- END_TIME=$(date +%s)
- START_TIME=${{ steps.start_time.outputs.timestamp }}
- DURATION=$((END_TIME - START_TIME))
- MINUTES=$((DURATION / 60))
- SECONDS=$((DURATION % 60))
- echo "duration=${MINUTES}m ${SECONDS}s" >> $GITHUB_OUTPUT
-
- - name: Update comment with success
- if: success()
- uses: actions/github-script@v7
- with:
- script: |
- const prNumber = ${{ fromJSON(steps.pr.outputs.result).number }};
- const sha = '${{ fromJSON(steps.pr.outputs.result).sha }}'.substring(0, 7);
- const commentId = ${{ steps.build_comment.outputs.result }};
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- const duration = '${{ steps.duration.outputs.duration }}';
- const pageUrl = '${{ steps.deployment.outputs.page_url }}';
-
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: commentId,
- body: `š **PR Test Deployment Complete!**\n\n` +
- `Hi, @${username}! Your PR test deployment is ready! ā
š\n\n` +
- `š View it here:\n` +
- `${pageUrl}${username}/${prNumber}/\n\n` +
- `**Details:**\n` +
- `- PR: #${prNumber}\n` +
- `- Commit: \`${sha}\`\n` +
- `- Requested by: @${username}\n` +
- `- Build time: ${duration}\n`
- });
-
- - name: Update comment with failure
- if: failure()
- uses: actions/github-script@v7
- with:
- script: |
- const commentId = ${{ steps.build_comment.outputs.result }};
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- const duration = '${{ steps.duration.outputs.duration }}';
-
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: commentId,
- body: `ā **PR Test Deployment Failed** @${username}\n\n` +
- `Something went wrong during build or deployment.\n` +
- `Build time: ${duration}\n\n` +
- `Check logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`
- });
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `ā
Checkout & Setup\n` +
- `${checklist_spinner} Installing dependencies\n` +
- `⬠Building\n` +
- `⬠Deploying`
- });
-
- - name: Install dependencies
- run: npm ci
-
- - name: Update comment - Building
- uses: actions/github-script@v7
- with:
- script: |
- const initial_spinner = '
';
- const checklist_spinner = '
';
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `ā
Checkout & Setup\n` +
- `ā
Installing dependencies\n` +
- `${checklist_spinner} Building\n` +
- `⬠Deploying`
- });
-
- - name: Build website
- run: npm run build
- env:
- NODE_ENV: production
-
- - name: Update comment - Deploying
- uses: actions/github-script@v7
- with:
- script: |
- const initial_spinner = '
';
- const checklist_spinner = '
';
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `ā
Checkout & Setup\n` +
- `ā
Installing dependencies\n` +
- `ā
Building\n` +
- `${checklist_spinner} Deploying to GitHub Pages`
- });
-
- - name: Prepare per-PR directory
- run: |
- mkdir -p ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}
- cp -r ./build/* ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}/
- touch ./public/.nojekyll
-
- - name: Upload Pages artifact
- uses: actions/upload-pages-artifact@v3
- with:
- path: ./public
-
- - name: Deploy to GitHub Pages
- id: deployment
- uses: actions/deploy-pages@v4
-
- - name: Calculate duration
- id: duration
- if: always()
- run: |
- END_TIME=$(date +%s)
- START_TIME=${{ steps.start_time.outputs.timestamp }}
- DURATION=$((END_TIME - START_TIME))
- MINUTES=$((DURATION / 60))
- SECONDS=$((DURATION % 60))
- echo "duration=${MINUTES}m ${SECONDS}s" >> $GITHUB_OUTPUT
-
- - name: Update comment with success
- if: success()
- uses: actions/github-script@v7
- with:
- script: |
- const prNumber = ${{ fromJSON(steps.pr.outputs.result).number }};
- const sha = '${{ fromJSON(steps.pr.outputs.result).sha }}'.substring(0, 7);
- const commentId = ${{ steps.build_comment.outputs.result }};
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- const duration = '${{ steps.duration.outputs.duration }}';
- const pageUrl = '${{ steps.deployment.outputs.page_url }}';
-
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: commentId,
- body: `š **PR Test Deployment Complete!**\n\n` +
- `Hi, @${username}! Your PR test deployment is ready! ā
š\n\n` +
- `š View it here:\n` +
- `${pageUrl}${username}/${prNumber}/\n\n` +
- `**Details:**\n` +
- `- PR: #${prNumber}\n` +
- `- Commit: \`${sha}\`\n` +
- `- Requested by: @${username}\n` +
- `- Build time: ${duration}\n`
- });
-
- - name: Update comment with failure
- if: failure()
- uses: actions/github-script@v7
- with:
- script: |
- const commentId = ${{ steps.build_comment.outputs.result }};
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- const duration = '${{ steps.duration.outputs.duration }}';
-
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: commentId,
- body: `ā **PR Test Deployment Failed** @${username}\n\n` +
- `Something went wrong during build or deployment.\n` +
- `Build time: ${duration}\n\n` +
- `Check logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`
- });
- body: `${spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `ā
Checkout & Setup\n` +
- `${spinner} Installing dependencies\n` +
- `⬠Building\n` +
- `⬠Deploying`
- });
-
- - name: Install dependencies
- run: npm ci
-
- - name: Update comment - Building
- uses: actions/github-script@v7
- with:
- script: |
- const spinner = '
';
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `ā
Checkout & Setup\n` +
- `ā
Installing dependencies\n` +
- `${spinner} Building\n` +
- `⬠Deploying`
- });
-
- - name: Build website
- run: npm run build
- env:
- NODE_ENV: production
-
- - name: Update comment - Deploying
- uses: actions/github-script@v7
- with:
- script: |
- const spinner = '
';
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `ā
Checkout & Setup\n` +
- `ā
Installing dependencies\n` +
- `ā
Building\n` +
- `${spinner} Deploying to GitHub Pages`
- });
-
- - name: Prepare per-PR directory
- run: |
- mkdir -p ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}
- cp -r ./build/* ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}/
- touch ./public/.nojekyll
-
- - name: Upload Pages artifact
- uses: actions/upload-pages-artifact@v3
- with:
- path: ./public
-
- - name: Deploy to GitHub Pages
- id: deployment
- uses: actions/deploy-pages@v4
-
- - name: Calculate duration
- id: duration
- if: always()
- run: |
- END_TIME=$(date +%s)
- START_TIME=${{ steps.start_time.outputs.timestamp }}
- DURATION=$((END_TIME - START_TIME))
- MINUTES=$((DURATION / 60))
- SECONDS=$((DURATION % 60))
- echo "duration=${MINUTES}m ${SECONDS}s" >> $GITHUB_OUTPUT
-
- - name: Update comment with success
- if: success()
- uses: actions/github-script@v7
- with:
- script: |
- const prNumber = ${{ fromJSON(steps.pr.outputs.result).number }};
- const sha = '${{ fromJSON(steps.pr.outputs.result).sha }}'.substring(0, 7);
- const commentId = ${{ steps.build_comment.outputs.result }};
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- const duration = '${{ steps.duration.outputs.duration }}';
- const pageUrl = '${{ steps.deployment.outputs.page_url }}';
-
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: commentId,
- body: `š **PR Test Deployment Complete!**\n\n` +
- `Hi, @${username}! Your PR test deployment is ready! ā
š\n\n` +
- `š View it here:\n` +
- `${pageUrl}${username}/${prNumber}/\n\n` +
- `**Details:**\n` +
- `- PR: #${prNumber}\n` +
- `- Commit: \`${sha}\`\n` +
- `- Requested by: @${username}\n` +
- `- Build time: ${duration}\n`
- });
-
- - name: Update comment with failure
- if: failure()
- uses: actions/github-script@v7
- with:
- script: |
- const commentId = ${{ steps.build_comment.outputs.result }};
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- const duration = '${{ steps.duration.outputs.duration }}';
-
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: commentId,
- body: `ā **PR Test Deployment Failed** @${username}\n\n` +
- `Something went wrong during build or deployment.\n` +
- `Build time: ${duration}\n\n` +
- `Check logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`
- });
- const duration = '${{ steps.duration.outputs.duration }}';
- const pageUrl = '${{ steps.deployment.outputs.page_url }}';
-
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: commentId,
- body: `š **PR Test Deployment Complete!**\n\n` +
- `Hi, @${username}! Your PR test deployment is ready! ā
š\n\n` +
- `š View it here:\n` +
- `${pageUrl}${username}/${prNumber}/\n\n` +
- `**Details:**\n` +
- `- PR: #${prNumber}\n` +
- `- Commit: \`${sha}\`\n` +
- `- Requested by: @${username}\n` +
- `- Build time: ${duration}\n`
- });
-
- - name: Update comment with failure
- if: failure()
- uses: actions/github-script@v7
- with:
- script: |
- const commentId = ${{ steps.build_comment.outputs.result }};
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- const duration = '${{ steps.duration.outputs.duration }}';
-
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: commentId,
- body: `ā **PR Test Deployment Failed** @${username}\n\n` +
- `Something went wrong during build or deployment.\n` +
- `Build time: ${duration}\n\n` +
- `Check logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`
- });
From 4305afd41848a071e15449d1f03a60cd43ca74bb Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Tue, 7 Oct 2025 21:45:29 -0400
Subject: [PATCH 14/43] Update prtest.yml
---
.github/workflows/prtest.yml | 369 +++++++++++++++++++++++++++++++++--
1 file changed, 354 insertions(+), 15 deletions(-)
diff --git a/.github/workflows/prtest.yml b/.github/workflows/prtest.yml
index bae437b28..b662f9240 100644
--- a/.github/workflows/prtest.yml
+++ b/.github/workflows/prtest.yml
@@ -67,29 +67,168 @@ jobs:
number: pr.data.number
};
- - name: Post building comment
+ ####################################################################
+ # Anti-spam confirmation:
+ # If a prior run for this PR happened within 10 minutes, require a
+ # reaction on a confirmation comment. This polls for a reaction up to
+ # 10 minutes (configurable).
+ ####################################################################
+ - name: Anti-spam: check recent run and require reaction if within 10m
+ id: anti_spam
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const prNumber = Number(${JSON.stringify("${{ fromJSON(steps.pr.outputs.result).number }}")});
+ const owner = context.repo.owner;
+ const repo = context.repo.repo;
+ const THREE_LETTERS = 'pr-test-deploy-comment'; // marker
+
+ // Get comments on the PR
+ const comments = await github.rest.issues.listComments({
+ owner, repo, issue_number: prNumber,
+ per_page: 100
+ });
+
+ // Find the first bot comment that contains our hidden marker and parse timestamp
+ let botComment = null;
+ let lastTimestamp = 0;
+ for (const c of comments.data) {
+ if (c.body && c.body.includes('')) {
+ botComment = c;
+ const m = /pr-test-deploy-timestamp:\s*(\d+)/.exec(c.body);
+ if (m) lastTimestamp = Number(m[1]);
+ break; // we edit the first match (sticky behavior)
+ }
+ }
+
+ const now = Math.floor(Date.now() / 1000);
+ const TEN_MIN = 10 * 60;
+
+ if (lastTimestamp && (now - lastTimestamp) < TEN_MIN) {
+ // Post a confirmation comment and wait for a reaction on it
+ const confirm = await github.rest.issues.createComment({
+ owner, repo, issue_number: prNumber,
+ body:
+`ā ļø **Quick confirmation required** ā ļø
+
+A PR test was already run less than 10 minutes ago. To prevent accidental spam, please **react to this comment with :rocket:** within 10 minutes to confirm you want to re-run the test.
+
+(If you prefer, reply with \`/confirm test pr\` as a comment.)`
+ });
+
+ const confirmCommentId = confirm.data.id;
+
+ // Poll for reactions up to 10 minutes
+ const until = Date.now() + TEN_MIN * 1000;
+ const pollIntervalMs = 10 * 1000; // 10s
+ let confirmed = false;
+
+ while (Date.now() < until) {
+ // list reactions for the confirmation comment
+ const reacts = await github.request('GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions', {
+ owner, repo, comment_id: confirmCommentId,
+ mediaType: { previews: ['squirrel-girl'] }
+ });
+ // Accept any reaction from a non-bot user (not the action)
+ for (const r of reacts.data) {
+ if (r.user && r.user.type !== 'Bot') {
+ confirmed = true;
+ break;
+ }
+ }
+ if (confirmed) break;
+ // Also check for a textual confirmation comment
+ const replies = await github.rest.issues.listComments({
+ owner, repo, issue_number: prNumber,
+ per_page: 100
+ });
+ for (const rep of replies.data) {
+ if (rep.body && rep.body.match(/\/confirm\s+test\s+pr/i) && rep.user.type !== 'Bot') {
+ confirmed = true;
+ break;
+ }
+ }
+ if (confirmed) break;
+ // sleep
+ await new Promise(r => setTimeout(r, pollIntervalMs));
+ }
+
+ if (!confirmed) {
+ // No confirmation ā stop the workflow early
+ core = require('@actions/core');
+ core.setFailed("No confirmation reaction received within 10 minutes. Cancelling test deployment to avoid spam.");
+ return { cancelled: "true" };
+ } else {
+ return { cancelled: "false" };
+ }
+ } else {
+ return { cancelled: "false" };
+ }
+
+ - name: Exit if anti-spam cancelled
+ if: steps.anti_spam.outputs.cancelled == 'true'
+ run: |
+ echo "Cancelled by anti-spam check. Exiting job."
+ exit 1
+
+ ####################################################################
+ # Sticky post / Create or update the single bot comment we use.
+ # We add a big heading, include a hidden marker and timestamp so
+ # future runs can find and update the same comment (sticky behavior).
+ ####################################################################
+ - name: Post or update sticky building comment
id: build_comment
uses: actions/github-script@v7
with:
script: |
- // Spinner for the main message (original larger one)
- const initial_spinner = '
';
- // Spinner for checklist items (new smaller one)
- const checklist_spinner = '
';
+ const prNumber = Number(${JSON.stringify("${{ fromJSON(steps.pr.outputs.result).number }}")});
+ const owner = context.repo.owner;
+ const repo = context.repo.repo;
const username = context.eventName === 'issue_comment'
? context.payload.comment.user.login
: context.payload.pull_request.user.login;
- const comment = await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: ${{ fromJSON(steps.pr.outputs.result).number }},
- body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `${checklist_spinner} Checkout & Setup\n` +
- `⬠Installing dependencies\n` +
- `⬠Building\n` +
- `⬠Deploying`
+
+ const initial_spinner = '
';
+ const checklist_spinner = '
';
+ const marker = '';
+ const timestamp = Math.floor(Date.now() / 1000);
+
+ // Find an existing bot comment with our marker (sticky)
+ const comments = await github.rest.issues.listComments({
+ owner, repo, issue_number: prNumber,
+ per_page: 100
});
- return comment.data.id;
+
+ let existing = null;
+ for (const c of comments.data) {
+ if (c.body && c.body.includes(marker)) {
+ existing = c;
+ break; // edit the first matching comment
+ }
+ }
+
+ const body = `# š§ Test PR Deployment\n\n` +
+ `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `${checklist_spinner} Checkout & Setup\n` +
+ `⬠Installing dependencies\n` +
+ `⬠Building\n` +
+ `⬠Deploying\n\n` +
+ `\n` +
+ `${marker}`;
+
+ if (existing) {
+ const updated = await github.rest.issues.updateComment({
+ owner, repo, comment_id: existing.id,
+ body
+ });
+ return updated.data.id;
+ } else {
+ const created = await github.rest.issues.createComment({
+ owner, repo, issue_number: prNumber,
+ body
+ });
+ return created.data.id;
+ }
- name: Checkout PR code
uses: actions/checkout@v4
@@ -103,6 +242,20 @@ jobs:
node-version: '20'
cache: 'npm'
+ ####################################################################
+ # Cache to speed up Puppeteer/Chromium and npm installs
+ # - caches npm cache and puppeteer chromium download directory
+ ####################################################################
+ - name: Cache npm and Puppeteer
+ uses: actions/cache@v4
+ with:
+ path: |
+ ~/.npm
+ ~/.cache/puppeteer
+ key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ env.GITHUB_SHA || github.run_id }}
+ restore-keys: |
+ ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-
+
- name: Update comment - Installing Dependencies
uses: actions/github-script@v7
with:
@@ -116,6 +269,192 @@ jobs:
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `${checklist_spinner} Installing dependencies\n` +
+ `⬠Building\n` +
+ `⬠Deploying\n\n` +
+ `\n` +
+ ``
+ });
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Update comment - Building
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const initial_spinner = '
';
+ const checklist_spinner = '
';
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `ā
Installing dependencies\n` +
+ `${checklist_spinner} Building\n` +
+ `⬠Deploying\n\n` +
+ `\n` +
+ ``
+ });
+
+ - name: Build website
+ run: npm run build
+ env:
+ NODE_ENV: production
+
+ - name: Update comment - Deploying
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const initial_spinner = '
';
+ const checklist_spinner = '
';
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `ā
Installing dependencies\n` +
+ `ā
Building\n` +
+ `${checklist_spinner} Deploying to GitHub Pages\n\n` +
+ `\n` +
+ ``
+ });
+
+ - name: Prepare per-PR directory
+ run: |
+ mkdir -p ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}
+ cp -r ./build/* ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}/
+ touch ./public/.nojekyll
+
+ - name: Upload Pages artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./public
+
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
+
+ - name: Calculate duration
+ id: duration
+ if: always()
+ run: |
+ END_TIME=$(date +%s)
+ START_TIME=${{ steps.start_time.outputs.timestamp }}
+ DURATION=$((END_TIME - START_TIME))
+ MINUTES=$((DURATION / 60))
+ SECONDS=$((DURATION % 60))
+ echo "duration=${MINUTES}m ${SECONDS}s" >> $GITHUB_OUTPUT
+
+ ####################################################################
+ # Screenshot step using Puppeteer:
+ # - installs puppeteer (cached), waits briefly for site to be ready,
+ # - captures a full-page screenshot, uploads as artifact,
+ # - updates the sticky comment with a link to the artifact and screenshot.
+ ####################################################################
+ - name: Take screenshot of deployed site (cached Puppeteer)
+ if: success()
+ env:
+ PAGE_URL: ${{ steps.deployment.outputs.page_url }}${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}/
+ run: |
+ set -e
+ # create a tiny Node script on the fly
+ cat > take_screenshot.js <<'NODE'
+ const fs = require('fs');
+ (async () => {
+ // lazy install puppeteer if not present (npm ci previously ran and cached chromium)
+ try {
+ const puppeteer = require('puppeteer');
+ const url = process.env.PAGE_URL;
+ const out = `screenshot-${process.env.GITHUB_RUN_ID || 'run'}.png`;
+ const browser = await puppeteer.launch({
+ args: ['--no-sandbox','--disable-setuid-sandbox']
+ });
+ const page = await browser.newPage();
+ // Wait a bit for pages with client-side rendering
+ await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 }).catch(()=>{});
+ await page.waitForTimeout(5000); // allow extra rendering time
+ await page.screenshot({ path: out, fullPage: true });
+ await browser.close();
+ console.log('SCREENSHOT_PATH=' + out);
+ fs.writeFileSync('/tmp/screenshot_path', out);
+ } catch (e) {
+ console.error('Screenshot failed:', e);
+ process.exit(0); // don't fail entire workflow if screenshot fails
+ }
+ })();
+ NODE
+
+ # ensure puppeteer is installed (leverages cached npm/artifacts)
+ if [ ! -d node_modules/puppeteer ]; then
+ echo "Installing puppeteer (cached when possible)..."
+ npm i puppeteer --no-audit --no-fund --silent
+ fi
+
+ node take_screenshot.js || true
+ continue-on-error: true
+
+ - name: Upload screenshot artifact (if any)
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: pr-test-screenshot-${{ github.run_id }}
+ path: |
+ screenshot-*.png
+ /tmp/screenshot_path
+
+ - name: Update comment with success
+ if: success()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const prNumber = ${{ fromJSON(steps.pr.outputs.result).number }};
+ const sha = '${{ fromJSON(steps.pr.outputs.result).sha }}'.substring(0, 7);
+ const commentId = ${{ steps.build_comment.outputs.result }};
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ const duration = '${{ steps.duration.outputs.duration }}';
+ const pageUrl = '${{ steps.deployment.outputs.page_url }}';
+ // Try to get screenshot artifact file name from /tmp/screenshot_path if present in runner workspace
+ const fs = require('fs');
+ let screenshotLine = '';
+ try {
+ if (fs.existsSync('/tmp/screenshot_path')) {
+ const p = fs.readFileSync('/tmp/screenshot_path', 'utf8').trim();
+ screenshotLine = `- Screenshot artifact: screenshot attached to workflow run (see "Artifacts" on this run).`;
+ } else {
+ // fallback note
+ screenshotLine = `- Screenshot: (no screenshot available)`;
+ }
+ } catch (e) {
+ screenshotLine = `- Screenshot: (error checking screenshot)`;
+ }
+
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: commentId,
+ body: `š **PR Test Deployment Complete!**\n\n` +
+ `Hi, @${username}! Your PR test deployment is ready! ā
š\n\n` +
+ `š View it here:\n` +
+ `${pageUrl}${username}/${prNumber}/\n\n` +
+ `**Details:**\n` +
+ `- PR: #${prNumber}\n` +
+ `- Commit: \`${sha}\`\n` + await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
`ā
Checkout & Setup\n` +
`${checklist_spinner} Installing dependencies\n` +
From 5d661463f71007d13e24ea01161e0894fe9a8afc Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Tue, 7 Oct 2025 21:49:43 -0400
Subject: [PATCH 15/43] Update prtest.yml
---
.github/workflows/prtest.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/prtest.yml b/.github/workflows/prtest.yml
index b662f9240..7cf347b67 100644
--- a/.github/workflows/prtest.yml
+++ b/.github/workflows/prtest.yml
@@ -73,7 +73,7 @@ jobs:
# reaction on a confirmation comment. This polls for a reaction up to
# 10 minutes (configurable).
####################################################################
- - name: Anti-spam: check recent run and require reaction if within 10m
+ - name: Anti-spam - check recent run and require reaction if within 10m
id: anti_spam
uses: actions/github-script@v7
with:
From ace05050cbf8aeb8a22054806958c6f740a6e475 Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Tue, 7 Oct 2025 22:00:27 -0400
Subject: [PATCH 16/43] Update prtest.yml
---
.github/workflows/prtest.yml | 450 ++++++++---------------------------
1 file changed, 96 insertions(+), 354 deletions(-)
diff --git a/.github/workflows/prtest.yml b/.github/workflows/prtest.yml
index 7cf347b67..f9b53ad40 100644
--- a/.github/workflows/prtest.yml
+++ b/.github/workflows/prtest.yml
@@ -67,167 +67,64 @@ jobs:
number: pr.data.number
};
- ####################################################################
- # Anti-spam confirmation:
- # If a prior run for this PR happened within 10 minutes, require a
- # reaction on a confirmation comment. This polls for a reaction up to
- # 10 minutes (configurable).
- ####################################################################
- - name: Anti-spam - check recent run and require reaction if within 10m
- id: anti_spam
+ # ---------- Sticky comment support: find existing comment with hidden marker ----------
+ - name: Find existing sticky comment
+ id: find_comment
uses: actions/github-script@v7
with:
script: |
- const prNumber = Number(${JSON.stringify("${{ fromJSON(steps.pr.outputs.result).number }}")});
- const owner = context.repo.owner;
- const repo = context.repo.repo;
- const THREE_LETTERS = 'pr-test-deploy-comment'; // marker
-
- // Get comments on the PR
+ // We'll look for an existing comment that contains the hidden marker so we can edit it
+ const issue_number = Number(${ { fromJSON(steps.pr.outputs.result).number }});
+ const marker = '';
const comments = await github.rest.issues.listComments({
- owner, repo, issue_number: prNumber,
- per_page: 100
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number
});
-
- // Find the first bot comment that contains our hidden marker and parse timestamp
- let botComment = null;
- let lastTimestamp = 0;
- for (const c of comments.data) {
- if (c.body && c.body.includes('')) {
- botComment = c;
- const m = /pr-test-deploy-timestamp:\s*(\d+)/.exec(c.body);
- if (m) lastTimestamp = Number(m[1]);
- break; // we edit the first match (sticky behavior)
- }
+ // Prefer bot comment with the marker, otherwise any comment with the marker
+ const found = comments.data.find(c => (c.user && c.user.type === 'Bot' && c.body && c.body.includes(marker)) || (c.body && c.body.includes(marker)));
+ if (found) {
+ return { comment_id: found.id };
}
+ return { comment_id: null };
- const now = Math.floor(Date.now() / 1000);
- const TEN_MIN = 10 * 60;
-
- if (lastTimestamp && (now - lastTimestamp) < TEN_MIN) {
- // Post a confirmation comment and wait for a reaction on it
- const confirm = await github.rest.issues.createComment({
- owner, repo, issue_number: prNumber,
- body:
-`ā ļø **Quick confirmation required** ā ļø
-
-A PR test was already run less than 10 minutes ago. To prevent accidental spam, please **react to this comment with :rocket:** within 10 minutes to confirm you want to re-run the test.
-
-(If you prefer, reply with \`/confirm test pr\` as a comment.)`
- });
-
- const confirmCommentId = confirm.data.id;
-
- // Poll for reactions up to 10 minutes
- const until = Date.now() + TEN_MIN * 1000;
- const pollIntervalMs = 10 * 1000; // 10s
- let confirmed = false;
-
- while (Date.now() < until) {
- // list reactions for the confirmation comment
- const reacts = await github.request('GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions', {
- owner, repo, comment_id: confirmCommentId,
- mediaType: { previews: ['squirrel-girl'] }
- });
- // Accept any reaction from a non-bot user (not the action)
- for (const r of reacts.data) {
- if (r.user && r.user.type !== 'Bot') {
- confirmed = true;
- break;
- }
- }
- if (confirmed) break;
- // Also check for a textual confirmation comment
- const replies = await github.rest.issues.listComments({
- owner, repo, issue_number: prNumber,
- per_page: 100
- });
- for (const rep of replies.data) {
- if (rep.body && rep.body.match(/\/confirm\s+test\s+pr/i) && rep.user.type !== 'Bot') {
- confirmed = true;
- break;
- }
- }
- if (confirmed) break;
- // sleep
- await new Promise(r => setTimeout(r, pollIntervalMs));
- }
-
- if (!confirmed) {
- // No confirmation ā stop the workflow early
- core = require('@actions/core');
- core.setFailed("No confirmation reaction received within 10 minutes. Cancelling test deployment to avoid spam.");
- return { cancelled: "true" };
- } else {
- return { cancelled: "false" };
- }
- } else {
- return { cancelled: "false" };
- }
-
- - name: Exit if anti-spam cancelled
- if: steps.anti_spam.outputs.cancelled == 'true'
- run: |
- echo "Cancelled by anti-spam check. Exiting job."
- exit 1
-
- ####################################################################
- # Sticky post / Create or update the single bot comment we use.
- # We add a big heading, include a hidden marker and timestamp so
- # future runs can find and update the same comment (sticky behavior).
- ####################################################################
- - name: Post or update sticky building comment
+ # ---------- Post building comment (create or update existing sticky comment) ----------
+ - name: Post or update building comment
id: build_comment
uses: actions/github-script@v7
with:
script: |
- const prNumber = Number(${JSON.stringify("${{ fromJSON(steps.pr.outputs.result).number }}")});
- const owner = context.repo.owner;
- const repo = context.repo.repo;
+ const initial_spinner = '
';
+ const checklist_spinner = '
';
const username = context.eventName === 'issue_comment'
? context.payload.comment.user.login
: context.payload.pull_request.user.login;
-
- const initial_spinner = '
';
- const checklist_spinner = '
';
- const marker = '';
- const timestamp = Math.floor(Date.now() / 1000);
-
- // Find an existing bot comment with our marker (sticky)
- const comments = await github.rest.issues.listComments({
- owner, repo, issue_number: prNumber,
- per_page: 100
- });
-
- let existing = null;
- for (const c of comments.data) {
- if (c.body && c.body.includes(marker)) {
- existing = c;
- break; // edit the first matching comment
- }
- }
-
- const body = `# š§ Test PR Deployment\n\n` +
- `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `${checklist_spinner} Checkout & Setup\n` +
- `⬠Installing dependencies\n` +
- `⬠Building\n` +
- `⬠Deploying\n\n` +
- `\n` +
- `${marker}`;
-
- if (existing) {
- const updated = await github.rest.issues.updateComment({
- owner, repo, comment_id: existing.id,
+ const issue_number = Number(${ { fromJSON(steps.pr.outputs.result).number }});
+ const marker = '';
+ const body = `${marker}\n${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `${checklist_spinner} Checkout & Setup\n` +
+ `⬠Installing dependencies\n` +
+ `⬠Building\n` +
+ `⬠Deploying`;
+
+ // If we found an existing comment, update it; otherwise create a new one
+ const existingId = ${ { fromJSON(steps.find_comment.outputs.result || '{}').comment_id || 'null' } };
+ if (existingId) {
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: existingId,
body
});
- return updated.data.id;
+ return existingId;
} else {
- const created = await github.rest.issues.createComment({
- owner, repo, issue_number: prNumber,
+ const comment = await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number,
body
});
- return created.data.id;
+ return comment.data.id;
}
- name: Checkout PR code
@@ -242,20 +139,6 @@ A PR test was already run less than 10 minutes ago. To prevent accidental spam,
node-version: '20'
cache: 'npm'
- ####################################################################
- # Cache to speed up Puppeteer/Chromium and npm installs
- # - caches npm cache and puppeteer chromium download directory
- ####################################################################
- - name: Cache npm and Puppeteer
- uses: actions/cache@v4
- with:
- path: |
- ~/.npm
- ~/.cache/puppeteer
- key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ env.GITHUB_SHA || github.run_id }}
- restore-keys: |
- ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-
-
- name: Update comment - Installing Dependencies
uses: actions/github-script@v7
with:
@@ -273,9 +156,7 @@ A PR test was already run less than 10 minutes ago. To prevent accidental spam,
`ā
Checkout & Setup\n` +
`${checklist_spinner} Installing dependencies\n` +
`⬠Building\n` +
- `⬠Deploying\n\n` +
- `\n` +
- ``
+ `⬠Deploying`
});
- name: Install dependencies
@@ -298,9 +179,7 @@ A PR test was already run less than 10 minutes ago. To prevent accidental spam,
`ā
Checkout & Setup\n` +
`ā
Installing dependencies\n` +
`${checklist_spinner} Building\n` +
- `⬠Deploying\n\n` +
- `\n` +
- ``
+ `⬠Deploying`
});
- name: Build website
@@ -325,9 +204,7 @@ A PR test was already run less than 10 minutes ago. To prevent accidental spam,
`ā
Checkout & Setup\n` +
`ā
Installing dependencies\n` +
`ā
Building\n` +
- `${checklist_spinner} Deploying to GitHub Pages\n\n` +
- `\n` +
- ``
+ `${checklist_spinner} Deploying to GitHub Pages`
});
- name: Prepare per-PR directory
@@ -345,185 +222,70 @@ A PR test was already run less than 10 minutes ago. To prevent accidental spam,
id: deployment
uses: actions/deploy-pages@v4
- - name: Calculate duration
- id: duration
- if: always()
+ # ---------- Screenshot step: run AFTER pages deploy (runs only on success) ----------
+ - name: Install puppeteer-core (fast, no Chromium download)
+ if: success()
run: |
- END_TIME=$(date +%s)
- START_TIME=${{ steps.start_time.outputs.timestamp }}
- DURATION=$((END_TIME - START_TIME))
- MINUTES=$((DURATION / 60))
- SECONDS=$((DURATION % 60))
- echo "duration=${MINUTES}m ${SECONDS}s" >> $GITHUB_OUTPUT
+ npm install --no-audit --no-fund puppeteer-core@latest
+ # npm cache is used above via setup-node cache to speed up installs
- ####################################################################
- # Screenshot step using Puppeteer:
- # - installs puppeteer (cached), waits briefly for site to be ready,
- # - captures a full-page screenshot, uploads as artifact,
- # - updates the sticky comment with a link to the artifact and screenshot.
- ####################################################################
- - name: Take screenshot of deployed site (cached Puppeteer)
+ - name: Take screenshot of deployed PR site
if: success()
- env:
- PAGE_URL: ${{ steps.deployment.outputs.page_url }}${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}/
+ id: take_screenshot
run: |
- set -e
- # create a tiny Node script on the fly
- cat > take_screenshot.js <<'NODE'
+ node <<'NODE_SCRIPT'
const fs = require('fs');
+ const path = require('path');
+ const puppeteer = require('puppeteer-core');
+
+ // Use runner's chrome executable (no chromium download)
+ const chromePaths = [
+ '/usr/bin/google-chrome-stable',
+ '/usr/bin/google-chrome',
+ '/usr/bin/chromium-browser',
+ '/usr/bin/chromium'
+ ];
+ const execPath = chromePaths.find(p => require('fs').existsSync(p));
+ if (!execPath) {
+ console.error('No bundled chrome found at expected paths. Attempting to launch without executablePath (may download Chromium).');
+ }
+
+ // Build target URL (same as in the success comment)
+ const username = process.env.GITHUB_ACTOR;
+ const prNumber = ${ { fromJSON(steps.pr.outputs.result).number } };
+ const pageRoot = process.env.PAGE_URL || '${{ steps.deployment.outputs.page_url }}';
+ const target = `${pageRoot}${username}/${prNumber}/`;
+
(async () => {
- // lazy install puppeteer if not present (npm ci previously ran and cached chromium)
+ const browser = await puppeteer.launch(execPath ? { executablePath: execPath, args: ['--no-sandbox', '--disable-setuid-sandbox'] } : { args: ['--no-sandbox', '--disable-setuid-sandbox']});
+ const page = await browser.newPage();
+ // give the site some extra time to settle
+ const waitMs = process.env.SCREENSHOT_WAIT_MS ? Number(process.env.SCREENSHOT_WAIT_MS) : 8000;
try {
- const puppeteer = require('puppeteer');
- const url = process.env.PAGE_URL;
- const out = `screenshot-${process.env.GITHUB_RUN_ID || 'run'}.png`;
- const browser = await puppeteer.launch({
- args: ['--no-sandbox','--disable-setuid-sandbox']
- });
- const page = await browser.newPage();
- // Wait a bit for pages with client-side rendering
- await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 }).catch(()=>{});
- await page.waitForTimeout(5000); // allow extra rendering time
- await page.screenshot({ path: out, fullPage: true });
+ await page.goto(target, { waitUntil: 'networkidle2', timeout: 60000 });
+ await page.waitForTimeout(waitMs);
+ // optional: set viewport large enough
+ await page.setViewport({ width: 1280, height: 900 });
+ const outPath = path.resolve('screenshot.png');
+ await page.screenshot({ path: outPath, fullPage: false });
+ console.log('Screenshot saved to', outPath);
+ await browser.close();
+ // print out so subsequent steps can reference it
+ console.log('::set-output name=path::' + outPath);
+ } catch (err) {
+ console.error('Error taking screenshot:', err);
await browser.close();
- console.log('SCREENSHOT_PATH=' + out);
- fs.writeFileSync('/tmp/screenshot_path', out);
- } catch (e) {
- console.error('Screenshot failed:', e);
- process.exit(0); // don't fail entire workflow if screenshot fails
+ process.exit(0); // do not fail the job if screenshot fails
}
})();
- NODE
+ NODE_SCRIPT
- # ensure puppeteer is installed (leverages cached npm/artifacts)
- if [ ! -d node_modules/puppeteer ]; then
- echo "Installing puppeteer (cached when possible)..."
- npm i puppeteer --no-audit --no-fund --silent
- fi
-
- node take_screenshot.js || true
- continue-on-error: true
-
- - name: Upload screenshot artifact (if any)
- if: always()
- uses: actions/upload-artifact@v4
- with:
- name: pr-test-screenshot-${{ github.run_id }}
- path: |
- screenshot-*.png
- /tmp/screenshot_path
-
- - name: Update comment with success
+ - name: Upload screenshot artifact
if: success()
- uses: actions/github-script@v7
- with:
- script: |
- const prNumber = ${{ fromJSON(steps.pr.outputs.result).number }};
- const sha = '${{ fromJSON(steps.pr.outputs.result).sha }}'.substring(0, 7);
- const commentId = ${{ steps.build_comment.outputs.result }};
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- const duration = '${{ steps.duration.outputs.duration }}';
- const pageUrl = '${{ steps.deployment.outputs.page_url }}';
- // Try to get screenshot artifact file name from /tmp/screenshot_path if present in runner workspace
- const fs = require('fs');
- let screenshotLine = '';
- try {
- if (fs.existsSync('/tmp/screenshot_path')) {
- const p = fs.readFileSync('/tmp/screenshot_path', 'utf8').trim();
- screenshotLine = `- Screenshot artifact: screenshot attached to workflow run (see "Artifacts" on this run).`;
- } else {
- // fallback note
- screenshotLine = `- Screenshot: (no screenshot available)`;
- }
- } catch (e) {
- screenshotLine = `- Screenshot: (error checking screenshot)`;
- }
-
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: commentId,
- body: `š **PR Test Deployment Complete!**\n\n` +
- `Hi, @${username}! Your PR test deployment is ready! ā
š\n\n` +
- `š View it here:\n` +
- `${pageUrl}${username}/${prNumber}/\n\n` +
- `**Details:**\n` +
- `- PR: #${prNumber}\n` +
- `- Commit: \`${sha}\`\n` + await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `ā
Checkout & Setup\n` +
- `${checklist_spinner} Installing dependencies\n` +
- `⬠Building\n` +
- `⬠Deploying`
- });
-
- - name: Install dependencies
- run: npm ci
-
- - name: Update comment - Building
- uses: actions/github-script@v7
- with:
- script: |
- const initial_spinner = '
';
- const checklist_spinner = '
';
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `ā
Checkout & Setup\n` +
- `ā
Installing dependencies\n` +
- `${checklist_spinner} Building\n` +
- `⬠Deploying`
- });
-
- - name: Build website
- run: npm run build
- env:
- NODE_ENV: production
-
- - name: Update comment - Deploying
- uses: actions/github-script@v7
- with:
- script: |
- const initial_spinner = '
';
- const checklist_spinner = '
';
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `ā
Checkout & Setup\n` +
- `ā
Installing dependencies\n` +
- `ā
Building\n` +
- `${checklist_spinner} Deploying to GitHub Pages`
- });
-
- - name: Prepare per-PR directory
- run: |
- mkdir -p ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}
- cp -r ./build/* ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}/
- touch ./public/.nojekyll
-
- - name: Upload Pages artifact
- uses: actions/upload-pages-artifact@v3
+ uses: actions/upload-artifact@v4
with:
- path: ./public
-
- - name: Deploy to GitHub Pages
- id: deployment
- uses: actions/deploy-pages@v4
+ name: pr-screenshot-${{ github.run_id }}
+ path: screenshot.png
- name: Calculate duration
id: duration
@@ -549,6 +311,8 @@ A PR test was already run less than 10 minutes ago. To prevent accidental spam,
: context.payload.pull_request.user.login;
const duration = '${{ steps.duration.outputs.duration }}';
const pageUrl = '${{ steps.deployment.outputs.page_url }}';
+ // Provide a link to artifacts for this run (artifact viewer for the run)
+ const artifactsLink = `${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}#artifacts`;
await github.rest.issues.updateComment({
owner: context.repo.owner,
@@ -562,26 +326,4 @@ A PR test was already run less than 10 minutes ago. To prevent accidental spam,
`- PR: #${prNumber}\n` +
`- Commit: \`${sha}\`\n` +
`- Requested by: @${username}\n` +
- `- Build time: ${duration}\n`
- });
-
- - name: Update comment with failure
- if: failure()
- uses: actions/github-script@v7
- with:
- script: |
- const commentId = ${{ steps.build_comment.outputs.result }};
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- const duration = '${{ steps.duration.outputs.duration }}';
-
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: commentId,
- body: `ā **PR Test Deployment Failed** @${username}\n\n` +
- `Something went wrong during build or deployment.\n` +
- `Build time: ${duration}\n\n` +
- `Check logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`
- });
+ `- Build
From a9eead257acce96d9a24d01de499cc863a611cd0 Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Tue, 7 Oct 2025 22:04:43 -0400
Subject: [PATCH 17/43] Update prtest.yml
---
.github/workflows/prtest.yml | 255 +++--------------------------------
1 file changed, 18 insertions(+), 237 deletions(-)
diff --git a/.github/workflows/prtest.yml b/.github/workflows/prtest.yml
index f9b53ad40..af3905999 100644
--- a/.github/workflows/prtest.yml
+++ b/.github/workflows/prtest.yml
@@ -67,263 +67,44 @@ jobs:
number: pr.data.number
};
- # ---------- Sticky comment support: find existing comment with hidden marker ----------
- - name: Find existing sticky comment
- id: find_comment
- uses: actions/github-script@v7
- with:
- script: |
- // We'll look for an existing comment that contains the hidden marker so we can edit it
- const issue_number = Number(${ { fromJSON(steps.pr.outputs.result).number }});
- const marker = '';
- const comments = await github.rest.issues.listComments({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number
- });
- // Prefer bot comment with the marker, otherwise any comment with the marker
- const found = comments.data.find(c => (c.user && c.user.type === 'Bot' && c.body && c.body.includes(marker)) || (c.body && c.body.includes(marker)));
- if (found) {
- return { comment_id: found.id };
- }
- return { comment_id: null };
-
- # ---------- Post building comment (create or update existing sticky comment) ----------
- - name: Post or update building comment
+ # Create or update a sticky comment (marker-based) with the build spinner + checklist
+ - name: Post or update building comment (sticky)
id: build_comment
uses: actions/github-script@v7
with:
script: |
+ const marker = '';
const initial_spinner = '
';
const checklist_spinner = '
';
+ const prNumber = context.eventName === 'issue_comment' ? context.issue.number : context.payload.number;
const username = context.eventName === 'issue_comment'
? context.payload.comment.user.login
: context.payload.pull_request.user.login;
- const issue_number = Number(${ { fromJSON(steps.pr.outputs.result).number }});
- const marker = '';
+ const issue_number = prNumber;
const body = `${marker}\n${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
`${checklist_spinner} Checkout & Setup\n` +
`⬠Installing dependencies\n` +
`⬠Building\n` +
`⬠Deploying`;
- // If we found an existing comment, update it; otherwise create a new one
- const existingId = ${ { fromJSON(steps.find_comment.outputs.result || '{}').comment_id || 'null' } };
- if (existingId) {
+ // Look for existing comment with marker (prefer bot-owned)
+ const comments = await github.rest.issues.listComments({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number
+ });
+
+ const found = comments.data.find(c => ((c.user && c.user.type === 'Bot') && c.body && c.body.includes(marker)) || (c.body && c.body.includes(marker)));
+
+ if (found) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
- comment_id: existingId,
+ comment_id: found.id,
body
});
- return existingId;
+ return { comment_id: found.id };
} else {
const comment = await github.rest.issues.createComment({
owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number,
- body
- });
- return comment.data.id;
- }
-
- - name: Checkout PR code
- uses: actions/checkout@v4
- with:
- ref: ${{ fromJSON(steps.pr.outputs.result).sha }}
- fetch-depth: 0
-
- - name: Setup Node.js
- uses: actions/setup-node@v4
- with:
- node-version: '20'
- cache: 'npm'
-
- - name: Update comment - Installing Dependencies
- uses: actions/github-script@v7
- with:
- script: |
- const initial_spinner = '
';
- const checklist_spinner = '
';
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `ā
Checkout & Setup\n` +
- `${checklist_spinner} Installing dependencies\n` +
- `⬠Building\n` +
- `⬠Deploying`
- });
-
- - name: Install dependencies
- run: npm ci
-
- - name: Update comment - Building
- uses: actions/github-script@v7
- with:
- script: |
- const initial_spinner = '
';
- const checklist_spinner = '
';
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `ā
Checkout & Setup\n` +
- `ā
Installing dependencies\n` +
- `${checklist_spinner} Building\n` +
- `⬠Deploying`
- });
-
- - name: Build website
- run: npm run build
- env:
- NODE_ENV: production
-
- - name: Update comment - Deploying
- uses: actions/github-script@v7
- with:
- script: |
- const initial_spinner = '
';
- const checklist_spinner = '
';
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: ${{ steps.build_comment.outputs.result }},
- body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `ā
Checkout & Setup\n` +
- `ā
Installing dependencies\n` +
- `ā
Building\n` +
- `${checklist_spinner} Deploying to GitHub Pages`
- });
-
- - name: Prepare per-PR directory
- run: |
- mkdir -p ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}
- cp -r ./build/* ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}/
- touch ./public/.nojekyll
-
- - name: Upload Pages artifact
- uses: actions/upload-pages-artifact@v3
- with:
- path: ./public
-
- - name: Deploy to GitHub Pages
- id: deployment
- uses: actions/deploy-pages@v4
-
- # ---------- Screenshot step: run AFTER pages deploy (runs only on success) ----------
- - name: Install puppeteer-core (fast, no Chromium download)
- if: success()
- run: |
- npm install --no-audit --no-fund puppeteer-core@latest
- # npm cache is used above via setup-node cache to speed up installs
-
- - name: Take screenshot of deployed PR site
- if: success()
- id: take_screenshot
- run: |
- node <<'NODE_SCRIPT'
- const fs = require('fs');
- const path = require('path');
- const puppeteer = require('puppeteer-core');
-
- // Use runner's chrome executable (no chromium download)
- const chromePaths = [
- '/usr/bin/google-chrome-stable',
- '/usr/bin/google-chrome',
- '/usr/bin/chromium-browser',
- '/usr/bin/chromium'
- ];
- const execPath = chromePaths.find(p => require('fs').existsSync(p));
- if (!execPath) {
- console.error('No bundled chrome found at expected paths. Attempting to launch without executablePath (may download Chromium).');
- }
-
- // Build target URL (same as in the success comment)
- const username = process.env.GITHUB_ACTOR;
- const prNumber = ${ { fromJSON(steps.pr.outputs.result).number } };
- const pageRoot = process.env.PAGE_URL || '${{ steps.deployment.outputs.page_url }}';
- const target = `${pageRoot}${username}/${prNumber}/`;
-
- (async () => {
- const browser = await puppeteer.launch(execPath ? { executablePath: execPath, args: ['--no-sandbox', '--disable-setuid-sandbox'] } : { args: ['--no-sandbox', '--disable-setuid-sandbox']});
- const page = await browser.newPage();
- // give the site some extra time to settle
- const waitMs = process.env.SCREENSHOT_WAIT_MS ? Number(process.env.SCREENSHOT_WAIT_MS) : 8000;
- try {
- await page.goto(target, { waitUntil: 'networkidle2', timeout: 60000 });
- await page.waitForTimeout(waitMs);
- // optional: set viewport large enough
- await page.setViewport({ width: 1280, height: 900 });
- const outPath = path.resolve('screenshot.png');
- await page.screenshot({ path: outPath, fullPage: false });
- console.log('Screenshot saved to', outPath);
- await browser.close();
- // print out so subsequent steps can reference it
- console.log('::set-output name=path::' + outPath);
- } catch (err) {
- console.error('Error taking screenshot:', err);
- await browser.close();
- process.exit(0); // do not fail the job if screenshot fails
- }
- })();
- NODE_SCRIPT
-
- - name: Upload screenshot artifact
- if: success()
- uses: actions/upload-artifact@v4
- with:
- name: pr-screenshot-${{ github.run_id }}
- path: screenshot.png
-
- - name: Calculate duration
- id: duration
- if: always()
- run: |
- END_TIME=$(date +%s)
- START_TIME=${{ steps.start_time.outputs.timestamp }}
- DURATION=$((END_TIME - START_TIME))
- MINUTES=$((DURATION / 60))
- SECONDS=$((DURATION % 60))
- echo "duration=${MINUTES}m ${SECONDS}s" >> $GITHUB_OUTPUT
-
- - name: Update comment with success
- if: success()
- uses: actions/github-script@v7
- with:
- script: |
- const prNumber = ${{ fromJSON(steps.pr.outputs.result).number }};
- const sha = '${{ fromJSON(steps.pr.outputs.result).sha }}'.substring(0, 7);
- const commentId = ${{ steps.build_comment.outputs.result }};
- const username = context.eventName === 'issue_comment'
- ? context.payload.comment.user.login
- : context.payload.pull_request.user.login;
- const duration = '${{ steps.duration.outputs.duration }}';
- const pageUrl = '${{ steps.deployment.outputs.page_url }}';
- // Provide a link to artifacts for this run (artifact viewer for the run)
- const artifactsLink = `${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}#artifacts`;
-
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: commentId,
- body: `š **PR Test Deployment Complete!**\n\n` +
- `Hi, @${username}! Your PR test deployment is ready! ā
š\n\n` +
- `š View it here:\n` +
- `${pageUrl}${username}/${prNumber}/\n\n` +
- `**Details:**\n` +
- `- PR: #${prNumber}\n` +
- `- Commit: \`${sha}\`\n` +
- `- Requested by: @${username}\n` +
- `- Build
+ repo: context
From f7c4255d06d08e7c9c0235345a6a3fd1a4f418db Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Tue, 7 Oct 2025 22:07:53 -0400
Subject: [PATCH 18/43] Update prtest.yml
---
.github/workflows/prtest.yml | 194 ++++++++++++++++++++++++++++++-----
1 file changed, 166 insertions(+), 28 deletions(-)
diff --git a/.github/workflows/prtest.yml b/.github/workflows/prtest.yml
index af3905999..bae437b28 100644
--- a/.github/workflows/prtest.yml
+++ b/.github/workflows/prtest.yml
@@ -67,44 +67,182 @@ jobs:
number: pr.data.number
};
- # Create or update a sticky comment (marker-based) with the build spinner + checklist
- - name: Post or update building comment (sticky)
+ - name: Post building comment
id: build_comment
uses: actions/github-script@v7
with:
script: |
- const marker = '';
+ // Spinner for the main message (original larger one)
const initial_spinner = '
';
+ // Spinner for checklist items (new smaller one)
const checklist_spinner = '
';
- const prNumber = context.eventName === 'issue_comment' ? context.issue.number : context.payload.number;
const username = context.eventName === 'issue_comment'
? context.payload.comment.user.login
: context.payload.pull_request.user.login;
- const issue_number = prNumber;
- const body = `${marker}\n${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
- `${checklist_spinner} Checkout & Setup\n` +
- `⬠Installing dependencies\n` +
- `⬠Building\n` +
- `⬠Deploying`;
-
- // Look for existing comment with marker (prefer bot-owned)
- const comments = await github.rest.issues.listComments({
+ const comment = await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
- issue_number
+ issue_number: ${{ fromJSON(steps.pr.outputs.result).number }},
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `${checklist_spinner} Checkout & Setup\n` +
+ `⬠Installing dependencies\n` +
+ `⬠Building\n` +
+ `⬠Deploying`
});
+ return comment.data.id;
- const found = comments.data.find(c => ((c.user && c.user.type === 'Bot') && c.body && c.body.includes(marker)) || (c.body && c.body.includes(marker)));
-
- if (found) {
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: found.id,
- body
- });
- return { comment_id: found.id };
- } else {
- const comment = await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context
+ - name: Checkout PR code
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ fromJSON(steps.pr.outputs.result).sha }}
+ fetch-depth: 0
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+ cache: 'npm'
+
+ - name: Update comment - Installing Dependencies
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const initial_spinner = '
';
+ const checklist_spinner = '
';
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `${checklist_spinner} Installing dependencies\n` +
+ `⬠Building\n` +
+ `⬠Deploying`
+ });
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Update comment - Building
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const initial_spinner = '
';
+ const checklist_spinner = '
';
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `ā
Installing dependencies\n` +
+ `${checklist_spinner} Building\n` +
+ `⬠Deploying`
+ });
+
+ - name: Build website
+ run: npm run build
+ env:
+ NODE_ENV: production
+
+ - name: Update comment - Deploying
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const initial_spinner = '
';
+ const checklist_spinner = '
';
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: ${{ steps.build_comment.outputs.result }},
+ body: `${initial_spinner} **Building PR for testing, requested by @${username}...**\n\n` +
+ `ā
Checkout & Setup\n` +
+ `ā
Installing dependencies\n` +
+ `ā
Building\n` +
+ `${checklist_spinner} Deploying to GitHub Pages`
+ });
+
+ - name: Prepare per-PR directory
+ run: |
+ mkdir -p ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}
+ cp -r ./build/* ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}/
+ touch ./public/.nojekyll
+
+ - name: Upload Pages artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./public
+
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
+
+ - name: Calculate duration
+ id: duration
+ if: always()
+ run: |
+ END_TIME=$(date +%s)
+ START_TIME=${{ steps.start_time.outputs.timestamp }}
+ DURATION=$((END_TIME - START_TIME))
+ MINUTES=$((DURATION / 60))
+ SECONDS=$((DURATION % 60))
+ echo "duration=${MINUTES}m ${SECONDS}s" >> $GITHUB_OUTPUT
+
+ - name: Update comment with success
+ if: success()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const prNumber = ${{ fromJSON(steps.pr.outputs.result).number }};
+ const sha = '${{ fromJSON(steps.pr.outputs.result).sha }}'.substring(0, 7);
+ const commentId = ${{ steps.build_comment.outputs.result }};
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ const duration = '${{ steps.duration.outputs.duration }}';
+ const pageUrl = '${{ steps.deployment.outputs.page_url }}';
+
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: commentId,
+ body: `š **PR Test Deployment Complete!**\n\n` +
+ `Hi, @${username}! Your PR test deployment is ready! ā
š\n\n` +
+ `š View it here:\n` +
+ `${pageUrl}${username}/${prNumber}/\n\n` +
+ `**Details:**\n` +
+ `- PR: #${prNumber}\n` +
+ `- Commit: \`${sha}\`\n` +
+ `- Requested by: @${username}\n` +
+ `- Build time: ${duration}\n`
+ });
+
+ - name: Update comment with failure
+ if: failure()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const commentId = ${{ steps.build_comment.outputs.result }};
+ const username = context.eventName === 'issue_comment'
+ ? context.payload.comment.user.login
+ : context.payload.pull_request.user.login;
+ const duration = '${{ steps.duration.outputs.duration }}';
+
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: commentId,
+ body: `ā **PR Test Deployment Failed** @${username}\n\n` +
+ `Something went wrong during build or deployment.\n` +
+ `Build time: ${duration}\n\n` +
+ `Check logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`
+ });
From d2c27d1699e0c6475cab4457bf2f9cc9dbff8d3d Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Wed, 8 Oct 2025 07:31:08 -0400
Subject: [PATCH 19/43] Update prtest.yml one last time
---
.github/workflows/prtest.yml | 43 ++++++++++++++++++++----------------
1 file changed, 24 insertions(+), 19 deletions(-)
diff --git a/.github/workflows/prtest.yml b/.github/workflows/prtest.yml
index bae437b28..9d4e71534 100644
--- a/.github/workflows/prtest.yml
+++ b/.github/workflows/prtest.yml
@@ -28,25 +28,7 @@ jobs:
id: start_time
run: echo "timestamp=$(date +%s)" >> $GITHUB_OUTPUT
- - name: Cancel previous runs
- uses: styfle/cancel-workflow-action@0.12.0
- with:
- workflow_id: 'prtest.yml'
- access_token: ${{ github.token }}
- all_but_latest: true
-
- - name: React to comment (if triggered by comment)
- if: github.event_name == 'issue_comment'
- uses: actions/github-script@v7
- with:
- script: |
- await github.rest.reactions.createForIssueComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: context.payload.comment.id,
- content: 'rocket'
- });
-
+ # Moved this step up to get branch for cancellation
- name: Get PR details
id: pr
uses: actions/github-script@v7
@@ -67,6 +49,29 @@ jobs:
number: pr.data.number
};
+ - name: Cancel previous runs
+ uses: styfle/cancel-workflow-action@0.12.0
+ with:
+ workflow_id: 'prtest.yml'
+ access_token: ${{ github.token }}
+ all_but_latest: true
+ # Cancel ONLY runs in the same PR branch
+ branch: ${{ fromJSON(steps.pr.outputs.result).ref }}
+
+ - name: React to comment (if triggered by comment)
+ if: github.event_name == 'issue_comment'
+ uses: actions/github-script@v7
+ with:
+ script: |
+ await github.rest.reactions.createForIssueComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: context.payload.comment.id,
+ content: 'rocket'
+ });
+
+ # Removed duplicate "Get PR details" step here (now handled above)
+
- name: Post building comment
id: build_comment
uses: actions/github-script@v7
From a9667740a7a53751e6d0b2aede443b75a416b456 Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Wed, 8 Oct 2025 07:55:42 -0400
Subject: [PATCH 20/43] Update prtest.yml
---
.github/workflows/prtest.yml | 65 ++++++++++++++++++++++++------------
1 file changed, 44 insertions(+), 21 deletions(-)
diff --git a/.github/workflows/prtest.yml b/.github/workflows/prtest.yml
index 9d4e71534..fc1467247 100644
--- a/.github/workflows/prtest.yml
+++ b/.github/workflows/prtest.yml
@@ -7,9 +7,8 @@ on:
types: [opened]
permissions:
- contents: read
+ contents: write # Added write permission for branch push
pull-requests: write
- pages: write
id-token: write
jobs:
@@ -19,16 +18,11 @@ jobs:
(github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '/test pr'))
runs-on: ubuntu-latest
- environment:
- name: github-pages
- url: ${{ steps.deployment.outputs.page_url }}
-
steps:
- name: Record start time
id: start_time
run: echo "timestamp=$(date +%s)" >> $GITHUB_OUTPUT
- # Moved this step up to get branch for cancellation
- name: Get PR details
id: pr
uses: actions/github-script@v7
@@ -55,7 +49,6 @@ jobs:
workflow_id: 'prtest.yml'
access_token: ${{ github.token }}
all_but_latest: true
- # Cancel ONLY runs in the same PR branch
branch: ${{ fromJSON(steps.pr.outputs.result).ref }}
- name: React to comment (if triggered by comment)
@@ -70,16 +63,12 @@ jobs:
content: 'rocket'
});
- # Removed duplicate "Get PR details" step here (now handled above)
-
- name: Post building comment
id: build_comment
uses: actions/github-script@v7
with:
script: |
- // Spinner for the main message (original larger one)
const initial_spinner = '
';
- // Spinner for checklist items (new smaller one)
const checklist_spinner = '
';
const username = context.eventName === 'issue_comment'
? context.payload.comment.user.login
@@ -182,18 +171,50 @@ jobs:
cp -r ./build/* ./public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}/
touch ./public/.nojekyll
- - name: Upload Pages artifact
- uses: actions/upload-pages-artifact@v3
+ # Checkout gh-pages branch (create if missing)
+ - name: Checkout gh-pages branch
+ id: checkout_gh_pages
+ uses: actions/checkout@v4
with:
- path: ./public
+ ref: gh-pages
+ path: gh-pages
+ token: ${{ secrets.GITHUB_TOKEN }}
+ fetch-depth: 0
+ continue-on-error: true
- - name: Deploy to GitHub Pages
- id: deployment
- uses: actions/deploy-pages@v4
+ # Initialize branch if it doesn't exist
+ - name: Create gh-pages branch if not exists
+ if: steps.checkout_gh_pages.outcome == 'failure'
+ run: |
+ mkdir -p gh-pages
+ cd gh-pages
+ git init -b gh-pages
+ git remote add origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git
+
+ # Sync built files to gh-pages directory
+ - name: Sync files to gh-pages
+ run: |
+ mkdir -p gh-pages/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}
+ cp -r public/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}/* gh-pages/${{ github.actor }}/${{ fromJSON(steps.pr.outputs.result).number }}/
+ cp public/.nojekyll gh-pages/ || true
+
+ # Commit and push changes
+ - name: Commit and push to gh-pages
+ run: |
+ cd gh-pages
+ git config user.name 'github-actions[bot]'
+ git config user.email 'github-actions[bot]@users.noreply.github.com'
+ git add .
+ if [ -n "$(git status --porcelain)" ]; then
+ git commit -m "Deploy PR ${{ fromJSON(steps.pr.outputs.result).number }} by ${{ github.actor }}"
+ git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git
+ git push origin gh-pages
+ else
+ echo "No changes to commit."
+ fi
- name: Calculate duration
id: duration
- if: always()
run: |
END_TIME=$(date +%s)
START_TIME=${{ steps.start_time.outputs.timestamp }}
@@ -214,7 +235,9 @@ jobs:
? context.payload.comment.user.login
: context.payload.pull_request.user.login;
const duration = '${{ steps.duration.outputs.duration }}';
- const pageUrl = '${{ steps.deployment.outputs.page_url }}';
+ // Manually construct deployment URL
+ const baseUrl = `https://${context.repo.owner}.github.io/${context.repo.repo}`;
+ const pageUrl = `${baseUrl}/${context.actor}/${prNumber}/`;
await github.rest.issues.updateComment({
owner: context.repo.owner,
@@ -223,7 +246,7 @@ jobs:
body: `š **PR Test Deployment Complete!**\n\n` +
`Hi, @${username}! Your PR test deployment is ready! ā
š\n\n` +
`š View it here:\n` +
- `${pageUrl}${username}/${prNumber}/\n\n` +
+ `${pageUrl}\n\n` +
`**Details:**\n` +
`- PR: #${prNumber}\n` +
`- Commit: \`${sha}\`\n` +
From fa2d557eab404bc3f9ab92a5ff2368fa5ac07a7a Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Wed, 8 Oct 2025 07:57:46 -0400
Subject: [PATCH 21/43] who the heck put v16 bro if you use v16 you better say
goodbye to your build it's freaking dying
it's v22
---
.nvmrc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.nvmrc b/.nvmrc
index 6f7f377bf..53d1c14db 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-v16
+v22
From 907a3b4d7b866d9a2e1ea69cc39726bcc44b91a9 Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Wed, 8 Oct 2025 07:57:58 -0400
Subject: [PATCH 22/43] rever
---
.nvmrc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.nvmrc b/.nvmrc
index 53d1c14db..6f7f377bf 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-v22
+v16
From f21f3cd6ca1aceda39af46b3361e6f4e334be18c Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Wed, 8 Oct 2025 07:58:33 -0400
Subject: [PATCH 23/43] who the heck put node v16 here bruh your builds gonna
die if you use it it's not supposed to be that
---
.nvmrc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.nvmrc b/.nvmrc
index 6f7f377bf..53d1c14db 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-v16
+v22
From 3362263343280ab2678917e50252f10fd89268a8 Mon Sep 17 00:00:00 2001
From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com>
Date: Wed, 8 Oct 2025 12:05:34 -0400
Subject: [PATCH 24/43] fix images when 404 is not in root
---
static/404.html | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/static/404.html b/static/404.html
index df9b13c33..5714a9821 100644
--- a/static/404.html
+++ b/static/404.html
@@ -1,11 +1,11 @@
OmniBlocks is a Multi-Language IDE in development, based on TurboWarp with enhanced features like a music editor. Future plans include text editors for Python, C, and more!
-Well, there is a man here.
+
There is a man here.
He offers you an egg. Take it?
You got the egg.
- It's an easter egg. Inside is a...
- OmniBlock?
+ It's an easter egg. Inside is an...
+ OmniBlock...?