From e09f455b81268004f1aa5b165c71e094a566f3c1 Mon Sep 17 00:00:00 2001 From: Ethan Arrowood Date: Wed, 17 Dec 2025 12:52:33 -0700 Subject: [PATCH 1/8] first pass --- .github/workflows/pr-preview.yaml | 186 ++++++++++++++++++++++++++ docs/developers/applications/index.md | 6 +- docs/index.mdx | 2 +- fabric/index.md | 2 +- versioned_docs/version-4.5/index.mdx | 2 +- versioned_docs/version-4.6/index.mdx | 2 +- versioned_docs/version-4.7/index.mdx | 2 +- 7 files changed, 194 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/pr-preview.yaml diff --git a/.github/workflows/pr-preview.yaml b/.github/workflows/pr-preview.yaml new file mode 100644 index 00000000..1056f3c6 --- /dev/null +++ b/.github/workflows/pr-preview.yaml @@ -0,0 +1,186 @@ +name: Deploy PR Preview + +on: + pull_request: + types: [opened, synchronize, reopened, closed] + +# Cancel previous runs when new commits are pushed to the PR +concurrency: + group: pr-preview-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + deploy-preview: + name: Deploy PR Preview + runs-on: ubuntu-latest + if: github.event.action != 'closed' + permissions: + pull-requests: write + deployments: write + contents: read + + steps: + - name: Checkout PR code + uses: actions/checkout@v6 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: '22' + cache: 'npm' + cache-dependency-path: 'package-lock.json' + + - name: Install dependencies + run: | + echo "Installing dependencies..." + npm ci + + - name: Build Docusaurus site + env: + DOCUSAURUS_BASE_URL: /pr-${{ github.event.pull_request.number }} + run: | + echo "Building site with base URL: $DOCUSAURUS_BASE_URL" + npm run build + + - name: Prepare deployment directory + run: | + PR_DIR="pr-${{ github.event.pull_request.number }}" + echo "Creating directory: $PR_DIR" + mkdir -p "$PR_DIR" + + # Create config.yaml + cat > "$PR_DIR/config.yaml" << 'EOF' + static: + files: 'build/**' + urlPath: 'pr-${{ github.event.pull_request.number }}' + extensions: ['html'] + index: true + EOF + + # Copy build directory + cp -r build "$PR_DIR/" + + echo "Contents of $PR_DIR:" + ls -la "$PR_DIR" + + - name: Install HarperDB CLI + run: | + npm install harperdb + + - name: Deploy to HarperDB + env: + HARPER_PREVIEW_TARGET: ${{ secrets.HARPER_PREVIEW_TARGET }} + HARPER_PREVIEW_USERNAME: ${{ secrets.HARPER_PREVIEW_USERNAME }} + HARPER_PREVIEW_PASSWORD: ${{ secrets.HARPER_PREVIEW_PASSWORD }} + run: | + cd "$PR_DIR" + # Add your additional arguments here + npx harper deploy \ + target=$HARPER_PREVIEW_TARGET \ + username=$HARPER_PREVIEW_USERNAME \ + password=$HARPER_PREVIEW_PASSWORD \ + project=pr-${{ github.event.pull_request.number }} \ + restart=true \ + replicated=true + + - name: Create deployment + env: + HARPER_PREVIEW_TARGET: ${{ secrets.HARPER_PREVIEW_TARGET }} + uses: actions/github-script@v8 + with: + script: | + const prNumber = context.payload.pull_request.number; + const target = process.env.HARPER_PREVIEW_TARGET; + const deploymentUrl = `${target}/pr-${prNumber}`; + + // Create deployment + const deployment = await github.rest.repos.createDeployment({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: context.payload.pull_request.head.sha, + environment: `pr-${prNumber}`, + description: `Preview deployment for PR #${prNumber}`, + auto_merge: false, + required_contexts: [] + }); + + // Create deployment status + await github.rest.repos.createDeploymentStatus({ + owner: context.repo.owner, + repo: context.repo.repo, + deployment_id: deployment.data.id, + state: 'success', + environment_url: deploymentUrl, + description: 'Preview deployment successful' + }); + + // Also add a comment to the PR + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: `## ๐Ÿš€ Preview Deployment\n\nYour preview deployment is ready!\n\n๐Ÿ”— **Preview URL:** ${deploymentUrl}\n\nThis preview will update automatically when you push new commits.` + }); + + cleanup-preview: + name: Cleanup PR Preview + runs-on: ubuntu-latest + if: github.event.action == 'closed' + permissions: + pull-requests: write + deployments: write + contents: read + + steps: + - name: Checkout code + uses: actions/checkout@v6 + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: '22' + cache: 'npm' + cache-dependency-path: 'package-lock.json' + + - name: Install HarperDB CLI + run: | + npm install harperdb + + - name: Remove preview deployment + run: | + # Add your cleanup command here (e.g., harper undeploy or similar) + npx harper drop-component project=pr-${{ github.event.pull_request.number }} replicated=true restart=true + echo "Cleaning up preview for PR #${{ github.event.pull_request.number }}" + + - name: Update deployment status + uses: actions/github-script@v7 + with: + script: | + const prNumber = context.payload.pull_request.number; + + // Mark deployment as inactive + const deployments = await github.rest.repos.listDeployments({ + owner: context.repo.owner, + repo: context.repo.repo, + environment: `pr-${prNumber}` + }); + + for (const deployment of deployments.data) { + await github.rest.repos.createDeploymentStatus({ + owner: context.repo.owner, + repo: context.repo.repo, + deployment_id: deployment.id, + state: 'inactive', + description: 'Preview deployment removed' + }); + } + + // Add cleanup comment to PR + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: `## ๐Ÿงน Preview Cleanup\n\nThe preview deployment for this PR has been removed.` + }); diff --git a/docs/developers/applications/index.md b/docs/developers/applications/index.md index 5122f875..8ac979ab 100644 --- a/docs/developers/applications/index.md +++ b/docs/developers/applications/index.md @@ -81,7 +81,7 @@ This guide is going to walk you through building a basic Harper application usin ## Custom Functionality with JavaScript -[The getting started guide](../../learn/) covers how to build an application entirely through schema configuration. However, if your application requires more custom functionality, you will probably want to employ your own JavaScript modules to implement more specific features and interactions. This gives you tremendous flexibility and control over how data is accessed and modified in Harper. Let's take a look at how we can use JavaScript to extend and define "resources" for custom functionality. In Harper, data is accessed through our [Resource API](../../reference/resources/), a standard interface to access data sources, tables, and make them available to endpoints. Database tables are `Resource` classes, and so extending the function of a table is as simple as extending their class. +[The getting started guide](/learn/) covers how to build an application entirely through schema configuration. However, if your application requires more custom functionality, you will probably want to employ your own JavaScript modules to implement more specific features and interactions. This gives you tremendous flexibility and control over how data is accessed and modified in Harper. Let's take a look at how we can use JavaScript to extend and define "resources" for custom functionality. In Harper, data is accessed through our [Resource API](../../reference/resources/), a standard interface to access data sources, tables, and make them available to endpoints. Database tables are `Resource` classes, and so extending the function of a table is as simple as extending their class. To define custom (JavaScript) resources as endpoints, we need to create a `resources.js` module (this goes in the root of your application folder). And then endpoints can be defined with Resource classes that `export`ed. This can be done in addition to, or in lieu of the `@export`ed types in the schema.graphql. If you are exporting and extending a table you defined in the schema make sure you remove the `@export` from the schema so that don't export the original table or resource to the same endpoint/path you are exporting with a class. Resource classes have methods that correspond to standard HTTP/REST methods, like `get`, `post`, `patch`, and `put` to implement specific handling for any of these methods (for tables they all have default implementations). Let's add a property to the dog records when they are returned, that includes their age in human years. To do this, we get the `Dog` class from the defined tables, extend it (with our custom logic), and export it: @@ -117,8 +117,8 @@ type Breed @table { We use the new table's (static) `get()` method to retrieve a breed by id. Harper will maintain the current context, ensuring that we are accessing the data atomically, in a consistent snapshot across tables. This provides: 1. Automatic tracking of most recently updated timestamps across resources for caching purposes -1. Sharing of contextual metadata (like user who requested the data) -1. Transactional atomicity for any writes (not needed in this get operation, but important for other operations) +2. Sharing of contextual metadata (like user who requested the data) +3. Transactional atomicity for any writes (not needed in this get operation, but important for other operations) The resource methods are automatically wrapped with a transaction and will automatically commit the changes when the method finishes. This allows us to fully utilize multiple resources in our current transaction. With our own snapshot of the database for the Dog and Breed table we can then access data like this: diff --git a/docs/index.mdx b/docs/index.mdx index 97b2b16c..b7943200 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -19,7 +19,7 @@ Here, you'll find all things Harper, and everything you need to get started, tro ## Getting Started -The best way to get started using Harper is to head over to the [Learn](../learn/) section and work through the Getting Started and Developer guides. +The best way to get started using Harper is to head over to the [Learn](/learn/) section and work through the Getting Started and Developer guides. ## Building with Harper diff --git a/fabric/index.md b/fabric/index.md index 573557ec..5afd0c30 100644 --- a/fabric/index.md +++ b/fabric/index.md @@ -8,7 +8,7 @@ Fabric Studio is the web-based GUI for Harper. Studio enables you to administer, [Sign up for free!](https://fabric.harper.fast/#/sign-up) -Harper includes a simplified local Studio that is packaged with all Harper installations and served directly from the cluster. It can be enabled in the [configuration file](../docs/deployments/configuration#localstudio). This section is dedicated to the hosted Studio accessed at [studio.harperdb.io](https://fabric.harper.fast/). +Harper includes a simplified local Studio that is packaged with all Harper installations and served directly from the cluster. It can be enabled in the [configuration file](/docs/deployments/configuration#localstudio). This section is dedicated to the hosted Studio accessed at [studio.harperdb.io](https://fabric.harper.fast/). --- diff --git a/versioned_docs/version-4.5/index.mdx b/versioned_docs/version-4.5/index.mdx index 8feac69a..d697bec7 100644 --- a/versioned_docs/version-4.5/index.mdx +++ b/versioned_docs/version-4.5/index.mdx @@ -17,7 +17,7 @@ Welcome to the Harper Documentation! Here, you'll find all things Harper, and ev ## Getting Started -The best way to get started using Harper is to head over to the [Learn](../../learn/) section and work through the Getting Started and Developer guides. +The best way to get started using Harper is to head over to the [Learn](/learn/) section and work through the Getting Started and Developer guides. ## Building with Harper diff --git a/versioned_docs/version-4.6/index.mdx b/versioned_docs/version-4.6/index.mdx index 7143837b..ee58c9ac 100644 --- a/versioned_docs/version-4.6/index.mdx +++ b/versioned_docs/version-4.6/index.mdx @@ -19,7 +19,7 @@ Here, you'll find all things Harper, and everything you need to get started, tro ## Getting Started -The best way to get started using Harper is to head over to the [Learn](../../learn/) section and work through the Getting Started and Developer guides. +The best way to get started using Harper is to head over to the [Learn](/learn/) section and work through the Getting Started and Developer guides. ## Building with Harper diff --git a/versioned_docs/version-4.7/index.mdx b/versioned_docs/version-4.7/index.mdx index 7143837b..ee58c9ac 100644 --- a/versioned_docs/version-4.7/index.mdx +++ b/versioned_docs/version-4.7/index.mdx @@ -19,7 +19,7 @@ Here, you'll find all things Harper, and everything you need to get started, tro ## Getting Started -The best way to get started using Harper is to head over to the [Learn](../../learn/) section and work through the Getting Started and Developer guides. +The best way to get started using Harper is to head over to the [Learn](/learn/) section and work through the Getting Started and Developer guides. ## Building with Harper From 1be1989f821c09d25341c9a58ab1d5d7e5239b9d Mon Sep 17 00:00:00 2001 From: Ethan Arrowood Date: Wed, 17 Dec 2025 13:14:06 -0700 Subject: [PATCH 2/8] fix workflow maybe --- .github/workflows/pr-preview.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-preview.yaml b/.github/workflows/pr-preview.yaml index 1056f3c6..37c0607e 100644 --- a/.github/workflows/pr-preview.yaml +++ b/.github/workflows/pr-preview.yaml @@ -75,9 +75,9 @@ jobs: HARPER_PREVIEW_USERNAME: ${{ secrets.HARPER_PREVIEW_USERNAME }} HARPER_PREVIEW_PASSWORD: ${{ secrets.HARPER_PREVIEW_PASSWORD }} run: | - cd "$PR_DIR" + cd "pr-${{ github.event.pull_request.number }}" # Add your additional arguments here - npx harper deploy \ + harper deploy \ target=$HARPER_PREVIEW_TARGET \ username=$HARPER_PREVIEW_USERNAME \ password=$HARPER_PREVIEW_PASSWORD \ From 5c51eda3fcdf19aafa516145a6faf1086b250057 Mon Sep 17 00:00:00 2001 From: Ethan Arrowood Date: Wed, 17 Dec 2025 13:38:12 -0700 Subject: [PATCH 3/8] try again --- .github/workflows/pr-preview.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-preview.yaml b/.github/workflows/pr-preview.yaml index 37c0607e..7825e697 100644 --- a/.github/workflows/pr-preview.yaml +++ b/.github/workflows/pr-preview.yaml @@ -77,8 +77,8 @@ jobs: run: | cd "pr-${{ github.event.pull_request.number }}" # Add your additional arguments here - harper deploy \ - target=$HARPER_PREVIEW_TARGET \ + npx harper deploy \ + target=${HARPER_PREVIEW_TARGET}:9925 \ username=$HARPER_PREVIEW_USERNAME \ password=$HARPER_PREVIEW_PASSWORD \ project=pr-${{ github.event.pull_request.number }} \ From a45fe1390ad8897b21a93bef4c442aed2f0a1991 Mon Sep 17 00:00:00 2001 From: Ethan Arrowood Date: Wed, 17 Dec 2025 14:03:02 -0700 Subject: [PATCH 4/8] beep boop --- .github/workflows/deploy.yaml | 26 ++++---------------------- .github/workflows/pr-preview.yaml | 19 ++++++++++++++++++- scripts/preview-pr.mjs | 24 ++++++++---------------- 3 files changed, 30 insertions(+), 39 deletions(-) diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 0059b385..21bc6dd7 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -1,8 +1,6 @@ name: Deploy Docusaurus to GitHub Pages on: - # Trigger the workflow on pull requests and pushes to specific branches - pull_request: push: branches: - main @@ -10,34 +8,20 @@ on: workflow_dispatch: # Concurrency configuration to manage parallel workflow runs -# -# Group composition: pages-- -# - event_type: 'pull_request', 'push', or 'workflow_dispatch' -# - unique_identifier: PR number for PRs, branch ref for pushes/manual runs -# -# Examples of group names: -# - PR #123: "pages-pull_request-123" -# - Push to main: "pages-push-refs/heads/main" -# - Manual run on main: "pages-workflow_dispatch-refs/heads/main" -# -# Behavior: -# - PRs: New commits cancel previous runs (cancel-in-progress: true) -# - Main branch: Runs complete without cancellation (cancel-in-progress: false) -# - Manual dispatch: Runs complete without cancellation (cancel-in-progress: false) concurrency: - group: pages-${{ github.event_name }}-${{ github.event_name == 'pull_request' && github.event.pull_request.number || github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: production-deploy + cancel-in-progress: false jobs: build: name: Build Docusaurus runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: fetch-depth: 0 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 with: node-version: '22' cache: 'npm' @@ -81,8 +65,6 @@ jobs: needs: build name: Deploy to GitHub Pages runs-on: ubuntu-latest - # Only deploy on push to main or manual trigger, not on PRs - if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || github.event_name == 'workflow_dispatch' permissions: pages: write diff --git a/.github/workflows/pr-preview.yaml b/.github/workflows/pr-preview.yaml index 7825e697..e55a9fea 100644 --- a/.github/workflows/pr-preview.yaml +++ b/.github/workflows/pr-preview.yaml @@ -44,6 +44,13 @@ jobs: echo "Building site with base URL: $DOCUSAURUS_BASE_URL" npm run build + - name: Upload build artifact for local testing + uses: actions/upload-artifact@v4 + with: + name: pr-${{ github.event.pull_request.number }}-build + path: build/ + retention-days: 30 + - name: Prepare deployment directory run: | PR_DIR="pr-${{ github.event.pull_request.number }}" @@ -149,9 +156,19 @@ jobs: npm install harperdb - name: Remove preview deployment + env: + HARPER_PREVIEW_TARGET: ${{ secrets.HARPER_PREVIEW_TARGET }} + HARPER_PREVIEW_USERNAME: ${{ secrets.HARPER_PREVIEW_USERNAME }} + HARPER_PREVIEW_PASSWORD: ${{ secrets.HARPER_PREVIEW_PASSWORD }} run: | # Add your cleanup command here (e.g., harper undeploy or similar) - npx harper drop-component project=pr-${{ github.event.pull_request.number }} replicated=true restart=true + npx harper drop-component \ + target=${HARPER_PREVIEW_TARGET}:9925 \ + username=$HARPER_PREVIEW_USERNAME \ + password=$HARPER_PREVIEW_PASSWORD \ + project=pr-${{ github.event.pull_request.number }} \ + replicated=true \ + restart=true echo "Cleaning up preview for PR #${{ github.event.pull_request.number }}" - name: Update deployment status diff --git a/scripts/preview-pr.mjs b/scripts/preview-pr.mjs index 48adef74..02b4bb77 100644 --- a/scripts/preview-pr.mjs +++ b/scripts/preview-pr.mjs @@ -98,7 +98,7 @@ async function main() { // Get the workflow run for this PR (using sanitized branch name) const runs = JSON.parse( execSync( - `gh api repos/HarperDB/documentation/actions/runs --paginate -X GET -f branch=${sanitizedBranch} --jq '.workflow_runs | map(select(.conclusion == "success" and .name == "Deploy Docusaurus to GitHub Pages")) | sort_by(.created_at) | reverse | .[0]'`, + `gh api repos/HarperDB/documentation/actions/runs --paginate -X GET -f branch=${sanitizedBranch} --jq '.workflow_runs | map(select(.conclusion == "success" and .name == "Deploy PR Preview")) | sort_by(.created_at) | reverse | .[0]'`, { encoding: 'utf-8' } ) ); @@ -126,10 +126,11 @@ async function main() { }) ); - const artifact = artifacts.find((a) => a.name === 'github-pages'); + const artifactName = `pr-${PR_NUMBER}-build`; + const artifact = artifacts.find((a) => a.name === artifactName); if (!artifact) { - console.error(`โŒ No 'github-pages' artifact found for this PR`); + console.error(`โŒ No '${artifactName}' artifact found for this PR`); process.exit(1); } @@ -170,18 +171,10 @@ async function main() { throw new Error('Downloaded artifact file not found'); } - // Extract the artifact (it's a tar.gz inside a zip) + // Extract the artifact (it's a direct zip of the build directory) console.log('๐Ÿ“‚ Extracting artifact...'); - execSync(`unzip -q "${artifactZip}" -d "${PR_DIR}"`, { stdio: 'inherit' }); - - // The github-pages artifact contains a tar.gz file - const tarFile = join(PR_DIR, 'artifact.tar'); - if (existsSync(tarFile)) { - mkdirSync(BUILD_DIR, { recursive: true }); - execSync(`tar -xzf "${tarFile}" -C "${BUILD_DIR}"`, { stdio: 'inherit' }); - } else { - throw new Error('Expected artifact.tar not found in artifact'); - } + mkdirSync(BUILD_DIR, { recursive: true }); + execSync(`unzip -q "${artifactZip}" -d "${BUILD_DIR}"`, { stdio: 'inherit' }); // Verify extracted files are within expected directory const resolvedBuildDir = join(BUILD_DIR); @@ -189,9 +182,8 @@ async function main() { throw new Error('Security violation: extracted files outside preview directory'); } - // Clean up compressed files + // Clean up zip file rmSync(artifactZip, { force: true }); - rmSync(tarFile, { force: true }); console.log('\nโœ… Preview ready!\n'); console.log(`๐Ÿ“ Build location: ${BUILD_DIR}`); From 05685e031364f77d9f4191ae3e17855d78833472 Mon Sep 17 00:00:00 2001 From: Ethan Arrowood Date: Thu, 18 Dec 2025 09:50:21 -0700 Subject: [PATCH 5/8] - to _ --- .github/workflows/pr-preview.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-preview.yaml b/.github/workflows/pr-preview.yaml index e55a9fea..a33ed357 100644 --- a/.github/workflows/pr-preview.yaml +++ b/.github/workflows/pr-preview.yaml @@ -162,7 +162,7 @@ jobs: HARPER_PREVIEW_PASSWORD: ${{ secrets.HARPER_PREVIEW_PASSWORD }} run: | # Add your cleanup command here (e.g., harper undeploy or similar) - npx harper drop-component \ + npx harper drop_component \ target=${HARPER_PREVIEW_TARGET}:9925 \ username=$HARPER_PREVIEW_USERNAME \ password=$HARPER_PREVIEW_PASSWORD \ From 442316d9ae5146881d1d50dd38325fe6ca84d3f4 Mon Sep 17 00:00:00 2001 From: Ethan Arrowood Date: Thu, 18 Dec 2025 10:18:05 -0700 Subject: [PATCH 6/8] fix preview-pr script --- scripts/preview-pr.mjs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/scripts/preview-pr.mjs b/scripts/preview-pr.mjs index 02b4bb77..8e9b3f6a 100644 --- a/scripts/preview-pr.mjs +++ b/scripts/preview-pr.mjs @@ -98,7 +98,7 @@ async function main() { // Get the workflow run for this PR (using sanitized branch name) const runs = JSON.parse( execSync( - `gh api repos/HarperDB/documentation/actions/runs --paginate -X GET -f branch=${sanitizedBranch} --jq '.workflow_runs | map(select(.conclusion == "success" and .name == "Deploy PR Preview")) | sort_by(.created_at) | reverse | .[0]'`, + `gh api repos/HarperFast/documentation/actions/runs --paginate -X GET -f branch=${sanitizedBranch} --jq '.workflow_runs | map(select(.conclusion == "success" and .name == "Deploy PR Preview")) | sort_by(.created_at) | reverse | .[0]'`, { encoding: 'utf-8' } ) ); @@ -121,7 +121,7 @@ async function main() { // Get the artifacts for this run const artifacts = JSON.parse( - execSync(`gh api repos/HarperDB/documentation/actions/runs/${runs.id}/artifacts --jq '.artifacts'`, { + execSync(`gh api repos/HarperFast/documentation/actions/runs/${runs.id}/artifacts --jq '.artifacts'`, { encoding: 'utf-8', }) ); @@ -162,7 +162,7 @@ async function main() { // Download the artifact console.log('โฌ‡๏ธ Downloading artifact...'); const artifactZip = join(PR_DIR, 'artifact.zip'); - execSync(`gh api repos/HarperDB/documentation/actions/artifacts/${artifact.id}/zip > "${artifactZip}"`, { + execSync(`gh api repos/HarperFast/documentation/actions/artifacts/${artifact.id}/zip > "${artifactZip}"`, { stdio: 'inherit', }); @@ -200,7 +200,10 @@ async function main() { console.log(`\n๐Ÿš€ Starting preview server...\n`); // Start the server with quoted path to prevent injection - execSync(`npm run serve -- --dir "${BUILD_DIR}"`, { stdio: 'inherit' }); + execSync(`npm run serve -- --dir "${BUILD_DIR}"`, { + stdio: 'inherit', + env: { ...process.env, DOCUSAURUS_BASE_URL: `pr-${PR_NUMBER}` }, + }); } catch (error) { console.error('\nโŒ Error:', error.message); process.exit(1); From 659c0572a0c1ed73fe21352e4f6a775a651af33a Mon Sep 17 00:00:00 2001 From: Ethan Arrowood Date: Thu, 18 Dec 2025 10:40:14 -0700 Subject: [PATCH 7/8] cancel-in-progress for deploy --- .github/workflows/deploy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 21bc6dd7..37519799 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -10,7 +10,7 @@ on: # Concurrency configuration to manage parallel workflow runs concurrency: group: production-deploy - cancel-in-progress: false + cancel-in-progress: true jobs: build: From 9ac9c1af9a26da7f8f63e50386b3d27c9ae25a25 Mon Sep 17 00:00:00 2001 From: Ethan Arrowood Date: Fri, 19 Dec 2025 08:10:35 -0700 Subject: [PATCH 8/8] fix fetch depth and global install harper --- .github/workflows/deploy.yaml | 2 -- .github/workflows/pr-preview.yaml | 8 ++++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 37519799..28b23cf6 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -18,8 +18,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - with: - fetch-depth: 0 - uses: actions/setup-node@v6 with: diff --git a/.github/workflows/pr-preview.yaml b/.github/workflows/pr-preview.yaml index a33ed357..0bd3303c 100644 --- a/.github/workflows/pr-preview.yaml +++ b/.github/workflows/pr-preview.yaml @@ -74,7 +74,7 @@ jobs: - name: Install HarperDB CLI run: | - npm install harperdb + npm install -g harperdb - name: Deploy to HarperDB env: @@ -84,7 +84,7 @@ jobs: run: | cd "pr-${{ github.event.pull_request.number }}" # Add your additional arguments here - npx harper deploy \ + harper deploy \ target=${HARPER_PREVIEW_TARGET}:9925 \ username=$HARPER_PREVIEW_USERNAME \ password=$HARPER_PREVIEW_PASSWORD \ @@ -153,7 +153,7 @@ jobs: - name: Install HarperDB CLI run: | - npm install harperdb + npm install -g harperdb - name: Remove preview deployment env: @@ -162,7 +162,7 @@ jobs: HARPER_PREVIEW_PASSWORD: ${{ secrets.HARPER_PREVIEW_PASSWORD }} run: | # Add your cleanup command here (e.g., harper undeploy or similar) - npx harper drop_component \ + harper drop_component \ target=${HARPER_PREVIEW_TARGET}:9925 \ username=$HARPER_PREVIEW_USERNAME \ password=$HARPER_PREVIEW_PASSWORD \