{"id":13998250,"url":"https://github.com/rossjrw/pr-preview-action","last_synced_at":"2026-01-20T12:00:38.909Z","repository":{"id":39494112,"uuid":"462466591","full_name":"rossjrw/pr-preview-action","owner":"rossjrw","description":"GitHub Action that deploys a pull request preview to GitHub Pages, similar to Vercel and Netlify, and cleans up after itself.","archived":false,"fork":false,"pushed_at":"2026-01-14T12:19:41.000Z","size":459,"stargazers_count":400,"open_issues_count":24,"forks_count":61,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-01-18T17:06:03.119Z","etag":null,"topics":["action","actions","deployment","gh-pages","github-actions","github-pages","pr-preview","preview","pull-requests","workflow"],"latest_commit_sha":null,"homepage":"https://github.com/marketplace/actions/deploy-pr-preview","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rossjrw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-02-22T20:39:32.000Z","updated_at":"2026-01-18T11:23:56.000Z","dependencies_parsed_at":"2025-04-13T11:45:41.882Z","dependency_job_id":"fbdd8696-e4b7-49b3-ae83-606a0c5d1dbc","html_url":"https://github.com/rossjrw/pr-preview-action","commit_stats":{"total_commits":81,"total_committers":16,"mean_commits":5.0625,"dds":0.2716049382716049,"last_synced_commit":"430e3dfc1de8a8ae77e77d862d25676ef9db55d1"},"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"purl":"pkg:github/rossjrw/pr-preview-action","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rossjrw%2Fpr-preview-action","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rossjrw%2Fpr-preview-action/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rossjrw%2Fpr-preview-action/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rossjrw%2Fpr-preview-action/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rossjrw","download_url":"https://codeload.github.com/rossjrw/pr-preview-action/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rossjrw%2Fpr-preview-action/sbom","scorecard":{"id":785226,"data":{"date":"2025-08-11","repo":{"name":"github.com/rossjrw/pr-preview-action","commit":"9f77b1d057b494e662c50b8ca40ecc63f21e0887"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.9,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/deploy-example.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/rossjrw/pr-preview-action/deploy-example.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/deploy-example.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/rossjrw/pr-preview-action/deploy-example.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/preview-example.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/rossjrw/pr-preview-action/preview-example.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/preview-example.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/rossjrw/pr-preview-action/preview-example.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:8: update your workflow using https://app.stepsecurity.io/secureworkflow/rossjrw/pr-preview-action/test.yml/main?enable=pin","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Code-Review","score":2,"reason":"Found 2/7 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":3,"reason":"2 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/deploy-example.yml:1","Warn: no topLevel permission defined: .github/workflows/preview-example.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 27 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-23T05:55:21.170Z","repository_id":39494112,"created_at":"2025-08-23T05:55:21.170Z","updated_at":"2025-08-23T05:55:21.170Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28603294,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T10:46:13.255Z","status":"ssl_error","status_checked_at":"2026-01-20T10:42:51.865Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["action","actions","deployment","gh-pages","github-actions","github-pages","pr-preview","preview","pull-requests","workflow"],"created_at":"2024-08-09T19:01:30.403Z","updated_at":"2026-01-20T12:00:38.881Z","avatar_url":"https://github.com/rossjrw.png","language":"Shell","funding_links":[],"categories":["Shell"],"sub_categories":[],"readme":"# Deploy PR Preview action\n\n[GitHub Action](https://github.com/features/actions) that deploys previews of pull requests to [GitHub Pages](https://pages.github.com/). Works on any repository with a GitHub Pages site.\n\nFeatures:\n\n-   Creates and deploys previews of pull requests to your GitHub Pages site\n-   Leaves a comment on the pull request with a link to the preview so that you and your team can collaborate on new features faster\n-   Updates the deployment and the comment whenever new commits are pushed to the pull request\n-   Includes a QR code in the preview comment for easy mobile access\n-   Cleans up after itself \u0026mdash; removes deployed previews when the pull request is closed\n-   Can be configured to override any of these behaviours\n\nPreview URLs look like this: `https://[owner].github.io/[repo]/pr-preview/pr-[number]/`\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/rossjrw/pr-preview-action/blob/main/.github/sample-preview-link.png\" alt=\"Sample comment left by the action\" width=\"548\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  Pictured: https://github.com/rossjrw/pr-preview-action/pull/1\n\u003c/p\u003e\n\nThis Action does not currently support deploying previews for PRs from forks, but will do so in [the upcoming v2](https://github.com/rossjrw/pr-preview-action/pull/6).\n\n# Setup\n\nA [GitHub Actions workflow](https://docs.github.com/en/actions/learn-github-actions) is required to use this Action.\n\nYou just need to do two things to set up your repository to support previews, both in the repository settings:\n\n### 1. Deploy Pages from branch\n\nEnsure that your repository is configured to have its GitHub Pages site deployed from a branch, by setting the source for the deployment under **Settings** \u003e **Pages** of your repository to **Deploy from branch**:\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/rossjrw/pr-preview-action/blob/main/.github/deployment-settings.png\" alt=\"GitHub Pages settings\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  Pictured: Repository Pages settings at /settings/page\n\u003c/p\u003e\n\n\u003e [!IMPORTANT]  \n\u003e The other option (called \"GitHub Actions\") has a [misleading name](https://github.com/orgs/community/discussions/30113#discussioncomment-7650234) and does not work with this action.\n\n### 2. Let your workflow write to the repo\n\nIn **Settings** \u003e **Actions** \u003e **General** \u003e **Workflow permissions**, select \"Read and write permissions\" to allow action runs to make changes to your deployment branch (in this case, to add and remove previews).\n\n# Usage\n\nAll the workflow needs to do before running the preview action is checkout the repository and build the Pages site.\n\nIf your GitHub pages site is deployed from the `gh-pages` branch, built with e.g. an `npm` script to the `./build/` dir, and you're happy with the default settings, usage is very simple:\n\n```yml\n# .github/workflows/preview.yml\nname: Deploy PR previews\n\non:\n    pull_request:\n        types:\n            - opened\n            - reopened\n            - synchronize\n            - closed\n\nconcurrency: preview-${{ github.ref }}\n\njobs:\n    deploy-preview:\n        runs-on: ubuntu-latest\n        steps:\n            - name: Checkout\n              uses: actions/checkout@v4\n\n            - name: Install and Build\n              if: github.event.action != 'closed' # We don't need the build if we know the preview will be removed\n              run: |\n                  npm install\n                  npm run build\n\n            - name: Deploy preview\n              uses: rossjrw/pr-preview-action@v1\n              with:\n                  source-dir: ./build/\n                  preview-branch: gh-pages\n                  qr-code: true\n```\n\n\u003e [!TIP]  \n\u003e The `gh-pages` branch is used for GitHub Pages deployments by convention, and will be used in examples here as well, but you can use whatever branch you like (just make sure to change the `preview-branch` input).\n\n## Inputs (configuration)\n\nThe following input parameters are provided, which can be passed to the `with` parameter. ALL parameters are optional and have a default value.\n\n| Input\u0026nbsp;parameter | Description |\n| --- | --- |\n| `source-dir` | When creating or updating a preview, the path to the directory that contains the files to deploy. E.g. if your project builds to `./dist/` you would put `./dist/` (or `dist`, etc.). \u003cbr\u003e Equivalent to [JamesIves/github-pages-deploy-action](https://github.com/JamesIves/github-pages-deploy-action) 'folder' setting. \u003cbr\u003e\u003cbr\u003e Default: `.` (repository root) |\n| `deploy-repository` | The repository to deploy the preview to. \u003cbr\u003e **Note:** The `token` parameter must also be set if changing this from the default. \u003cbr\u003e\u003cbr\u003e Default: The pull request's target repository. |\n| `preview-branch` | Branch to save previews to. This should be the same branch that your GitHub Pages site is deployed from. \u003cbr\u003e\u003cbr\u003e Default: `gh-pages` |\n| `umbrella-dir` | Path to the directory to place previews in. \u003cbr\u003e The umbrella directory is used to namespace previews from your main branch's deployment on GitHub Pages. \u003cbr\u003e\u003cbr\u003e Default: `pr-preview` |\n| `pr-number` | The PR number to use for the preview path. \u003cbr\u003e Useful for testing or when the workflow is not triggered by a pull_request event. \u003cbr\u003e\u003cbr\u003e Default: The PR number (`${{ github.event.number }}`) |\n| `pages-base-url` | Base URL to use when providing a link to the preview site. \u003cbr\u003e\u003cbr\u003e Default: The pull request's target repository's default GitHub Pages URL (e.g. `rossjrw.github.io/pr-preview-action/`) |\n| `pages-base-path` | Path that GitHub Pages is being served from, as configured in your repository settings, e.g. `docs/`. When generating the preview URL path, this is removed from the beginning of the file path. \u003cbr\u003e\u003cbr\u003e Default: `.` (repository root) |\n| `wait-for-pages-deployment` \u003cbr\u003e (boolean) | Whether to wait for the GitHub Pages deployment to complete. When enabled, the action will poll the GitHub Deployments API and delay workflow completion until the Pages deployment finishes, e.g. to ensure the preview URL is accessible when the comment is posted. \u003cbr\u003e\u003cbr\u003e Default: `false` (this will be `true` in a future version of this Action) |\n| `comment` \u003cbr\u003e (boolean) | Whether to leave a [sticky comment](https://github.com/marocchino/sticky-pull-request-comment) on the PR after the preview is built.\u003cbr\u003e The comment may be added before the preview finishes deploying unless `wait-for-pages-deployment` is enabled. \u003cbr\u003e\u003cbr\u003e Default: `true` |\n| `qr-code` \u003cbr\u003e | Whether to include a QR code in the sticky comment for easy mobile access, which links to the preview URL. Only affects the default comment (i.e. if `comment` is not `false`). \u003cbr\u003e Enabled by default - set to `false` to disable, or to a string to use a different provider ([see below](#use-a-different-qr-code-provider)). \u003cbr\u003e\u003cbr\u003e Default: [`https://qr.rossjrw.com/?color.dark=0d1117\u0026url=`](https://qr.rossjrw.com) |\n| `token` | Authentication token for the preview deployment. \u003cbr\u003e The default value works for non-fork pull requests to the same repository. For anything else, you will need a [Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) with permission to access it, and [store it as a secret](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions) in your repository. E.g. you might name that secret 'PREVIEW_TOKEN' and use it with `token: ${{ secrets.PREVIEW_TOKEN }}`. \u003cbr\u003e\u003cbr\u003e Default: `${{ github.token }}`, which gives the action permission to deploy to the current repository. |\n| `action` \u003cbr\u003e (enum) | Determines what this action will do when it is executed. Supported values: \u003cbr\u003e\u003cbr\u003e \u003cul\u003e\u003cli\u003e`deploy` - create and deploy the preview, overwriting any existing preview in that location.\u003c/li\u003e\u003cli\u003e`remove` - remove the preview.\u003c/li\u003e\u003cli\u003e`auto` - determine whether to deploy or remove the preview based on [the emitted event](https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#pull_request). If the event is `pull_request`, it will deploy the preview when the event type is `opened`, `reopened` and `synchronize`, and remove it on `closed` events. Does not do anything for other events or event types, even if you explicitly instruct the workflow to run on them.\u003c/li\u003e\u003cli\u003e`none` and all other values: does not do anything.\u003c/li\u003e\u003c/ul\u003e Default: `auto` |\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eExtra parameters for controlling the commits\u003c/b\u003e\u003c/summary\u003e\n\n| Input\u0026nbsp;parameter | Description |\n| --- | --- |\n| `deploy-commit-message` | The commit message to use when adding/updating a preview. \u003cbr\u003e **Note:** You can use certain [GitHub context variables](https://docs.github.com/en/actions/reference/workflows-and-actions/contexts). \u003cbr\u003e\u003cbr\u003e Default: `Deploy preview for PR ${{ github.event.number }} 🛫` |\n| `remove-commit-message` | The commit message to use when removing a preview. \u003cbr\u003e Note: If using `action` with a value of `\"auto\"`, you need to specify BOTH `deploy-commit-message` and `remove-commit-message`. \u003cbr\u003e\u003cbr\u003e Default: `Remove preview for PR ${{ github.event.number }} 🛬` |\n| `git-config-name` | The git user.name to use for the deployment commit. \u003cbr\u003e\u003cbr\u003e Default: The user who created the `token` |\n| `git-config-email` | The git user.email to use for the deployment commit. \u003cbr\u003e\u003cbr\u003e Default: The user who created the `token` |\n\n\u003c/details\u003e\n\n## Outputs\n\nSeveral output values are provided to use after this Action in your workflow. To use them, give this Action's step an `id` and reference the value with `${{ steps.\u003cid\u003e.outputs.\u003cname\u003e }}`, e.g.:\n\n```yml\n# .github/workflows/preview.yml\njobs:\n    deploy-preview:\n        steps:\n            - uses: rossjrw/pr-preview-action@v1\n              id: preview-step\n            - if: steps.preview-step.outputs.deployment-action == \"deploy\"\n              run: echo \"Preview visible at ${{ steps.preview-step.outputs.preview-url }}\"\n```\n\nYou could use these outputs and input parameter `comment: false` to write your own sticky comment after the Action has run.\n\n| Output | Description |\n| --- | --- |\n| `deployment-action` | Resolved value of the `action` input parameter (deploy, remove, none). |\n| `pages-base-url` | What this Action thinks the base URL of the GitHub Pages site is. |\n| `preview-url-path` | Path to the preview from the Pages base URL. |\n| `preview-url` | Full URL to the preview (`https://\u003cpages-base-url\u003e/\u003cpreview-url-path\u003e/`). |\n| `deployed-commit-sha` | The SHA of the commit that was deployed to the preview branch. |\n| `action-version` | The full, exact version of this Action when it was run. |\n| `action-start-timestamp` | The time that the workflow step started as a Unix timestamp. |\n| `action-start-time` | The time that the workflow step started in a readable format (UTC, depending on runner). |\n\n# Considerations\n\n## Common pitfalls\n\n### Grant Actions permission to read and write to the repository\n\nThis must be changed in the repository settings by selecting \"Read and write permissions\" at **Settings** \u003e **Actions** \u003e **General** \u003e **Workflow permissions**. Otherwise, the Action won't be able to make any changes to your deployment branch.\n\n### Run on all appropriate pull request events\n\nBe sure to [pick the right event types](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request) for the `pull_request` event. It only comes with `opened`, `reopened`, and `synchronize` by default \u0026mdash; but this Action assumes by default that the preview should be removed during the `closed` event, which it only sees if you explicitly add it to the workflow.\n\n### Ensure your main deployment is compatible\n\nIf you are using GitHub Actions to deploy your GitHub Pages sites (typically on push to the main branch), there are some actions you should take to avoid the PR preview overwriting the main deployment, or vice-versa.\n\n1. **Prevent your main deployment from deleting previews**\n\n    If your root directory on the GitHub Pages deployment branch (or `docs/` on the main branch) is generated automatically (e.g. on pushes to the main branch, with a tool such as Webpack), you will need to configure it not to remove the umbrella directory (`pr-preview/` by default, see configuration below).\n\n    For example, if you are using [JamesIves/github-pages-deploy-action](https://github.com/JamesIves/github-pages-deploy-action) to deploy your build, you can implement this using its `clean-exclude` parameter:\n\n    ```yml\n    # .github/workflows/build-deploy-pages-site.yml\n    steps:\n        ...\n        - uses: JamesIves/github-pages-deploy-action@v4\n          ...\n          with:\n              clean-exclude: pr-preview/\n              ...\n    ```\n\n    If you don't do this, your main deployment may delete all of your currently-existing PR previews.\n\n2. **Don't force-push your main deployment**\n\n    Force-pushing your main deployment will cause it to overwrite any and all files in the deployment location. This will destroy any ongoing preview deployments. Instead, consider adjusting your deployment workflow to rebase or merge your main deployment onto the deployment branch to respect other ongoing deployments.\n\n    For example, if you are using [JamesIves/github-pages-deploy-action](https://github.com/JamesIves/github-pages-deploy-action) to deploy your build, be aware that at the time of writing (v4.7.2) it force-pushes new deployments by default. You can disable this by setting its `force` parameter to `false`, which will prompt it to rebase new deployments instead of force-pushing them:\n\n    ```yml\n    # .github/workflows/build-deploy-pages-site.yml\n    steps:\n        ...\n        - uses: JamesIves/github-pages-deploy-action@v4\n            ...\n            with:\n                force: false\n                ...\n    ```\n\n    This feature was introduced in v4.3.0 of the above Action.\n\n## Best practices\n\n### Run only when files are changed\n\nConsider limiting this workflow to run [only when relevant files are edited](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onpushpull_requestpull_request_targetpathspaths-ignore) to avoid deploying previews unnecessarily.\n\n### Set a concurrency group\n\nI highly recommend [setting a concurrency group](https://docs.github.com/en/actions/using-jobs/using-concurrency) scoped to each PR using `github.ref` as above, which should prevent the preview and comment from desynchronising if you are e.g. committing very frequently.\n\n## Examples\n\n### Full example\n\nFull example with all default values added:\n\n```yml\n# .github/workflows/preview.yml\nname: Deploy PR previews\nconcurrency: preview-${{ github.ref }}\non:\n    pull_request:\n        types:\n            - opened\n            - reopened\n            - synchronize\n            - closed\njobs:\n    deploy-preview:\n        runs-on: ubuntu-latest\n        steps:\n            - uses: actions/checkout@v4\n            - run: npm i \u0026\u0026 npm run build\n              if: github.event.action != 'closed'\n            - uses: rossjrw/pr-preview-action@v1\n              with:\n                  source-dir: .\n                  preview-branch: gh-pages\n                  umbrella-dir: pr-preview\n                  action: auto\n                  wait-for-pages-deployment: false\n                  comment: true\n                  qr-code: false\n```\n\n...and an accompanying main deployment workflow:\n\n```yml\n# .github/workflows/deploy.yml\nname: Deploy\non:\n    push:\n        branches:\n            - main\njobs:\n    deploy:\n        runs-on: ubuntu-latest\n        steps:\n            - uses: actions/checkout@v4\n            - run: npm i \u0026\u0026 npm run build\n            - uses: JamesIves/github-pages-deploy-action@v4\n              with:\n                  folder: .\n                  branch: gh-pages\n                  clean-exclude: pr-preview\n                  force: false\n```\n\n### Deployment from `docs/`\n\nIf your Pages site is built to `build/` and deployed from the `docs/` directory on the `main` branch:\n\n```yml\n# .github/workflows/preview.yml\nsteps:\n    ...\n    - uses: rossjrw/pr-preview-action@v1\n      with:\n          source-dir: build\n          preview-branch: main\n          umbrella-dir: docs/pr-preview\n          pages-base-path: docs\n```\n\nYou should definitely limit this workflow to run only on changes to directories other than `docs/`, otherwise this workflow will call itself recursively.\n\n### Only remove previews for unmerged PRs\n\nInformation from the [context](https://docs.github.com/en/actions/reference/workflows-and-actions/contexts) and [conditionals](https://docs.github.com/en/actions/reference/workflows-and-actions/expressions) can be used to make more complex decisions about what to do with previews; for example, removing only those associated with _unmerged_ PRs when they are closed:\n\n```yml\n# .github/workflows/preview.yml\nsteps:\n    ...\n    - uses: rossjrw/pr-preview-action@v1\n      if: contains(['opened', 'reopened', 'synchronize'], github.event.action)\n      with:\n          source-dir: ./build/\n          action: deploy\n    - uses: rossjrw/pr-preview-action@v1\n      if: github.event.action == \"closed\" \u0026\u0026 !github.event.pull_request.merged\n      with:\n          source-dir: ./build/\n          action: remove\n```\n\n### Permanent previews\n\nIf you want to keep PR previews around forever, even after the associated PR has been closed, you don't want the cleanup behaviour of `auto` \u0026mdash; call `deploy` and never call `remove`:\n\n```yml\n# .github/workflows/everlasting-preview.yml\nname: Deploy everlasting PR preview\nconcurrency: preview-${{ github.ref }}\non:\n    pull_request:\n        types:\n            - opened\n            - synchronize\njobs:\n    deploy-preview:\n        runs-on: ubuntu-latest\n        steps:\n            - uses: actions/checkout@v4\n            - run: npm i \u0026\u0026 npm run build\n            - uses: rossjrw/pr-preview-action@v1\n              with:\n                  source-dir: ./build/\n                  action: deploy\n```\n\n### Wait for GitHub Pages deployment to complete\n\nBy default, this action starts a deployment to the target branch and leaves a comment immediately, but GitHub Pages may take 30-60 seconds to build and deploy your site. This can result in comments with preview links that don't work yet.\n\nSet `wait-for-deployment: true` to make the action automatically wait for Pages deployment before posting the comment:\n\n```yml\n- uses: rossjrw/pr-preview-action@v1\n  with:\n      wait-for-pages-deployment: true\n```\n\n### Customise the sticky comment\n\nYou can use `id`, `with: comment: false`, the output values and [context variables](https://docs.github.com/en/actions/reference/workflows-and-actions/contexts) to construct your own comment to be left on the PR. This example recreates this Action's default comment (complete with HTML spacing jank), but you could change it however you like, use a different commenting Action from the marketplace, etc.\n\n```yml\n# .github/workflows/preview.yml\nname: Deploy PR preview\nconcurrency: preview-${{ github.ref }}\non:\n    pull_request:\n        types:\n            - opened\n            - reopened\n            - synchronize\n            - closed\nenv:\n    PREVIEW_BRANCH: gh-pages\njobs:\n    deploy-preview:\n        runs-on: ubuntu-latest\n        steps:\n            - uses: actions/checkout@v4\n            - run: npm i \u0026\u0026 npm run build\n\n            - uses: rossjrw/pr-preview-action@v1\n              id: preview-step\n              with:\n                  source-dir: ./build/\n                  preview-branch: ${{ env.PREVIEW_BRANCH }}\n                  comment: false\n\n            - uses: marocchino/sticky-pull-request-comment@v2\n              if: steps.preview-step.outputs.deployment-action == 'deploy' \u0026\u0026 env.deployment_status == 'success'\n              with:\n                  header: pr-preview\n                  message: |\n                      [PR Preview Action](https://github.com/rossjrw/pr-preview-action) ${{ steps.preview-step.outputs.action-version }}\n                      :---:\n                      | \u003cp\u003e\u003cimg src=\"https://qr.rossjrw.com/?url=${{ steps.preview-step.outputs.preview-url }}\" height=\"100\" align=\"right\" alt=\"QR code for preview link\"\u003e\u003c/p\u003e :rocket: View preview at \u003cbr\u003e ${{ steps.preview-step.outputs.preview-url }} \u003cbr\u003e\u003cbr\u003e\n                      | \u003ch6\u003eBuilt to branch [`${{ env.PREVIEW_BRANCH }}`](${{ github.server_url }}/${{ github.repository }}/tree/${{ env.PREVIEW_BRANCH }}) at ${{ steps.preview-step.outputs.action-start-time }}. \u003cbr\u003e Preview will be ready when the [GitHub Pages deployment](${{ github.server_url }}/${{ github.repository }}/deployments) is complete. \u003cbr\u003e\u003cbr\u003e \u003c/h6\u003e\n\n            - uses: marocchino/sticky-pull-request-comment@v2\n              if: steps.preview-step.outputs.deployment-action == 'remove' \u0026\u0026 env.deployment_status == 'success'\n              with:\n                  header: pr-preview\n                  message: |\n                      [PR Preview Action](https://github.com/rossjrw/pr-preview-action) ${{ steps.preview-step.outputs.action-version }}\n                      :---:\n                      Preview removed because the pull request was closed.\n                      ${{ steps.preview-step.outputs.action-start-time }}\n```\n\n### Use a different QR code provider\n\nIf you have this action include a QR code in the sticky comment with `qr-code: true`, the default QR code provider is [qr.rossjrw.com](https://qr.rossjrw.com/), a provider that I built for this project because I don't trust any pre-existing ones. Likewise, you probably shouldn't trust mine - what if I go rogue and change all your QR codes to point to something else? You never know.\n\nTo use a different QR code provider (it's easy to make your own - consider forking https://github.com/rossjrw/qrcode-worker), set `qr-code` to its URL. The URI-encoded preview link will be appended to it. E.g.:\n\n```yml\n- uses: rossjrw/pr-preview-action@v1\n  with:\n      qr-code: https://my-qrcode-provider.example.com/generate?url=\n```\n\nIf using a customised comment with `comment: false`, simply construct the image URL from your chosen provider's URL and the preview URL (`${{ steps.[JOB ID].outputs.preview-url }}`).\n\n# Acknowledgements\n\nBig thanks to the following:\n\n-   [shlinkio/deploy-preview-action](https://github.com/shlinkio/deploy-preview-action) (MIT), prior art that informed the direction of this Action\n-   [JamesIves/github-pages-deploy-action](https://github.com/JamesIves/github-pages-deploy-action) (MIT), used by this Action to deploy previews\n-   [marocchino/sticky-pull-request-comment](https://github.com/marocchino/sticky-pull-request-comment) (MIT), used by this Action to leave a sticky comment on pull requests\n-   [Everyone who has contributed](https://github.com/rossjrw/pr-preview-action/graphs/contributors) to this Action\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frossjrw%2Fpr-preview-action","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frossjrw%2Fpr-preview-action","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frossjrw%2Fpr-preview-action/lists"}