{"id":13596185,"url":"https://github.com/afc163/surge-preview","last_synced_at":"2026-06-06T07:01:05.249Z","repository":{"id":38272325,"uuid":"287170895","full_name":"afc163/surge-preview","owner":"afc163","description":"🔂 Preview website in surge.sh for every pull request.","archived":false,"fork":false,"pushed_at":"2026-06-05T06:44:28.000Z","size":1394,"stargazers_count":156,"open_issues_count":4,"forks_count":27,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-06-05T07:07:22.107Z","etag":null,"topics":["actions","github-actions","preview-deploy","surge-sh"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/afc163.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2020-08-13T03:22:21.000Z","updated_at":"2026-06-05T06:24:11.000Z","dependencies_parsed_at":"2024-01-16T22:19:08.487Z","dependency_job_id":"1721784a-0546-4891-896d-e06c1694fed5","html_url":"https://github.com/afc163/surge-preview","commit_stats":{"total_commits":157,"total_committers":13,"mean_commits":"12.076923076923077","dds":0.4394904458598726,"last_synced_commit":"a17bbee72e236f18b248797bbf21f1f9f06900e6"},"previous_names":[],"tags_count":26,"template":false,"template_full_name":"actions/typescript-action","purl":"pkg:github/afc163/surge-preview","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afc163%2Fsurge-preview","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afc163%2Fsurge-preview/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afc163%2Fsurge-preview/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afc163%2Fsurge-preview/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/afc163","download_url":"https://codeload.github.com/afc163/surge-preview/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afc163%2Fsurge-preview/sbom","scorecard":{"id":169466,"data":{"date":"2025-08-11","repo":{"name":"github.com/afc163/surge-preview","commit":"2eeb59677bf6ace680164a2f3f69795ceff6d486"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.1,"checks":[{"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":"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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/preview.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":"Code-Review","score":7,"reason":"Found 13/18 approved changesets -- score normalized to 7","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":"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":"Maintained","score":3,"reason":"3 commit(s) and 1 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":"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/preview.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/afc163/surge-preview/preview.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/preview.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/afc163/surge-preview/preview.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/afc163/surge-preview/test.yml/main?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/test.yml:18","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 npmCommand 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":"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":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"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":"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":"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":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 25 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-16T16:00:19.238Z","repository_id":38272325,"created_at":"2025-08-16T16:00:19.238Z","updated_at":"2025-08-16T16:00:19.238Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33972398,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-06T02:00:07.033Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["actions","github-actions","preview-deploy","surge-sh"],"created_at":"2024-08-01T16:02:11.419Z","updated_at":"2026-06-06T07:01:05.232Z","avatar_url":"https://github.com/afc163.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# 🔂 Surge PR Preview\n\n**A GitHub Action that deploys a live preview of your website to [surge.sh](https://surge.sh/) for every pull request.**\n\n[![CI status][ci-image]][ci-url]\n[![Marketplace][marketplace-image]][marketplace-url]\n[![Release][release-image]][release-url]\n[![License][license-image]][license-url]\n\n[ci-image]: https://github.com/afc163/surge-preview/workflows/build-test/badge.svg\n[ci-url]: https://github.com/afc163/surge-preview/actions?query=workflow%3Abuild-test\n[marketplace-image]: https://img.shields.io/badge/marketplace-surge--pr--preview-blue?logo=github\n[marketplace-url]: https://github.com/marketplace/actions/surge-pr-preview\n[release-image]: https://img.shields.io/github/v/release/afc163/surge-preview?sort=semver\u0026logo=github\n[release-url]: https://github.com/afc163/surge-preview/releases\n[license-image]: https://img.shields.io/github/license/afc163/surge-preview\n[license-url]: https://github.com/afc163/surge-preview/blob/main/LICENSE\n\n\u003c/div\u003e\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd width=\"55%\"\u003e\u003cimg alt=\"PR preview comment\" src=\"https://github.com/user-attachments/assets/e247df64-975d-4ee3-90ee-13eb994b3f17\"\u003e\u003c/td\u003e\n    \u003ctd width=\"45%\"\u003e\u003cimg alt=\"Preview website\" src=\"https://github.com/user-attachments/assets/068ad690-3b7d-4ef4-a80c-a3663d99d5e7\"\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n## ✨ Why surge-preview?\n\nCompared to Netlify / Vercel:\n\n- 🆓 **It is free.**\n- 🧩 **It supports multiple preview jobs.**\n\n## 📖 Table of Contents\n\n- [Usage](#-usage)\n  - [Multiple Jobs](#multiple-jobs)\n  - [Teardown](#teardown)\n  - [PRs from Forked Repositories](#-prs-from-forked-repositories)\n- [Inputs](#-inputs)\n- [Outputs](#-outputs)\n- [Who is using it?](#-who-is-using-it)\n- [Thanks to](#-thanks-to)\n\n## 🚀 Usage\n\nAdd a workflow (`.github/workflows/preview.yml`):\n\n```yaml\nname: 🔂 Surge PR Preview\n\non: [pull_request]\n\njobs:\n  preview:\n    runs-on: ubuntu-latest\n    permissions:\n      pull-requests: write # allow surge-preview to create/update PR comments\n    steps:\n      - uses: actions/checkout@v4\n      - uses: afc163/surge-preview@v1\n        id: preview_step\n        with:\n          surge_token: ${{ secrets.SURGE_TOKEN }}\n          dist: public\n          build: |\n            npm install\n            npm run build\n      - name: Get the preview_url\n        run: echo \"url =\u003e ${{ steps.preview_step.outputs.preview_url }}\"\n```\n\nThe preview website url will be `https://{{repository.owner}}-{{repository.name}}-{{job.name}}-pr-{{pr.number}}.surge.sh`.\n\n### Multiple Jobs\n\n```yaml\nname: 🔂 Surge PR Preview\n\non: [pull_request]\n\npermissions:\n  pull-requests: write # allow surge-preview to create/update PR comments\n\njobs:\n  preview-job-1:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: afc163/surge-preview@v1\n        with:\n          surge_token: ${{ secrets.SURGE_TOKEN }}\n          dist: public\n          build: |\n            npm install\n            npm run build\n  preview-job-2:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: afc163/surge-preview@v1\n        with:\n          surge_token: ${{ secrets.SURGE_TOKEN }}\n          dist: public\n          build: |\n            npm install\n            npm run build\n```\n\nThe preview website urls will be:\n\n- `https://{{repository.owner}}-{{repository.name}}-preview-job-1-pr-{{pr.number}}.surge.sh`\n- `https://{{repository.owner}}-{{repository.name}}-preview-job-2-pr-{{pr.number}}.surge.sh`\n\n### Teardown\n\nWhen a pull request is closed and `teardown` is set to `'true'`, the surge instance will be destroyed.\n\n```yaml\nname: 🔂 Surge PR Preview\n\non:\n  pull_request:\n    # when using teardown: 'true', add default event types + closed event type (for teardown)\n    types: [opened, synchronize, reopened, closed]\n  push:\n\njobs:\n  preview:\n    runs-on: ubuntu-latest\n    permissions:\n      pull-requests: write # allow surge-preview to create/update PR comments\n    steps:\n      - uses: actions/checkout@v4\n      - uses: afc163/surge-preview@v1\n        with:\n          surge_token: ${{ secrets.SURGE_TOKEN }}\n          dist: public\n          teardown: 'true'\n          build: |\n            npm install\n            npm run build\n```\n\n## 🔐 PRs from Forked Repositories\n\nWhen someone creates a PR from a forked repository, there is a security challenge: workflows triggered by `pull_request` events do not have access to your repository secrets (like your surge token) for security reasons.\n\n\u003e [!WARNING]\n\u003e **Why this is a problem:** Without access to the surge token, the preview deployment will fail.\n\n\u003e [!CAUTION]\n\u003e **Why not use `pull_request_target`?** While this event does provide access to secrets, it executes code from the PR branch with your secrets, creating a security risk. Attackers could potentially steal your secrets by submitting malicious PRs.\n\u003e\n\u003e Resources:\n\u003e - https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/\n\u003e - https://github.com/afc163/surge-preview/commit/4931cbc38d650f631f91974da3ccd4809c88aa1b and https://github.com/afc163/surge-preview/issues/99\n\n### Solution: Use a three-workflow approach\n\nThis approach separates the build and deployment steps for improved security:\n\n1. **Build workflow** — builds the site without needing secrets, then saves it as an artifact.\n2. **Deploy workflow** — retrieves the artifact and deploys the pre-built site using your secrets.\n3. **Teardown workflow** — removes the preview when a PR is closed.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eBuild workflow\u003c/b\u003e (triggered by \u003ccode\u003epull_request\u003c/code\u003e)\u003c/summary\u003e\n\n```yaml\nname: Surge PR Preview - Build Stage\n\non:\n  pull_request:\n\njobs:\n  build-preview:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v4\n      - name: Build site\n        env:\n          PR_NUMBER: ${{ github.event.pull_request.number }}\n        # Generate a random page, containing the number of the PR\n        # Replace with your actual build command\n        run: |\n          mkdir site\n          cp -r public/surge/* site/\n          sed -i \"s/@PR_NUMBER@/${PR_NUMBER}/g\" site/index.html\n\n      - name: Upload site artifact\n        uses: actions/upload-artifact@v4\n        with:\n          name: pr-build-dist # Important: use this same name in the deploy workflow\n          path: site/\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eDeploy workflow\u003c/b\u003e (triggered by \u003ccode\u003eworkflow_run\u003c/code\u003e, when the build workflow completes)\u003c/summary\u003e\n\n```yaml\nname: Surge PR Preview - Deploy Stage\n\non:\n  workflow_run:\n    workflows: [\"Surge PR Preview - Build Stage\"]\n    types:\n      - completed\n\npermissions:\n  pull-requests: write # Needed to comment on PRs\n\njobs:\n  # Important - the job id:\n  # MUST be unique across all surge preview deployments for a repository as the job id is used in the deployment URL\n  # MUST be kept in sync with the job id of the teardown stage (this id is used by the surge-preview action to forge the deployment URL)\n  deploy:\n    runs-on: ubuntu-latest\n    if: ${{ github.event.workflow_run.event == 'pull_request' \u0026\u0026 github.event.workflow_run.conclusion == 'success' }}\n\n    steps:\n      - name: Download built site\n        uses: dawidd6/action-download-artifact@v8\n        with:\n          workflow: ${{ github.event.workflow_run.workflow_id }}\n          run_id: ${{ github.event.workflow_run.id }}\n          name: pr-build-dist  # Must match the name from build workflow\n          path: site/\n\n      - name: Deploy to Surge\n        uses: afc163/surge-preview@v1\n        with:\n          surge_token: ${{ secrets.SURGE_TOKEN }}\n          github_token: ${{ secrets.GITHUB_TOKEN }}\n          build: echo done\n          dist: site\n          failOnError: true\n          teardown: false # Teardown is handled by the separate workflow\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eTeardown workflow\u003c/b\u003e (triggered when a PR is closed)\u003c/summary\u003e\n\n```yaml\nname: Surge PR Preview - Teardown Stage\n\non:\n  pull_request_target:\n    types: [closed]\n\npermissions:\n  pull-requests: write # Needed to comment on PRs\n\njobs:\n  deploy: # Must match the job ID from the deploy workflow\n    runs-on: ubuntu-latest\n    steps:\n      - name: Teardown preview site\n        uses: afc163/surge-preview@v1\n        with:\n          surge_token: ${{ secrets.SURGE_TOKEN }}\n          github_token: ${{ secrets.GITHUB_TOKEN }}\n          failOnError: true\n          teardown: true\n          build: echo \"Cleaning up preview\" \n```\n\n\u003c/details\u003e\n\n### Troubleshooting\n\nWhen running the workflow triggered by `workflow_run` event, the surge-preview action retrieves the number of the Pull Request associated with the workflow run by doing API calls.\n\nOccasionally, the API call may hit rate limits, as the search API can use many calls internally. In this case, the error is caught and a warning is logged. Re-running the workflow should resolve the issue.\n\n\u003e [!TIP]\n\u003e As a workaround, you can use a [Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#about-personal-access-tokens) instead of the `GITHUB_TOKEN`: a PAT has higher rate limits, so the API calls are more likely to succeed.\n\u003e\n\u003e **Note**: Using a PAT as the `github_token` input has a side effect: the PR comment created by the action will be created by the account to which the PAT belongs. When using `GITHUB_TOKEN`, the PR comments are created by the GitHub Actions bot.\n\n### Limitations\n\nIn some situations, it is hard to know if the surge deployment has been done.\n\nWhen a workflow is triggered by `workflow_run`, it does not appear in the PR checks, so you cannot see whether the workflow has run or if it has failed. By default, there is no status on the commit. It is possible to add this manually in the workflow, for example by using [set-commit-status-action](https://github.com/myrotvorets/set-commit-status-action).\n\nHowever, when the workflow runs, the usual comment is updated by the `surge-preview` action to indicate whether the deployment is in progress or if the Surge deployment succeeded or failed.\n\n## ⚙️ Inputs\n\n| Parameter       | Description                                                                                                                       | Default                                                                                                                                  |\n|-----------------|-----------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------|\n| `surge_token`   | [Getting your Surge token](https://surge.sh/help/integrating-with-circleci).                                                      | An arbitrary token for demonstration. Use your own, otherwise anybody using this action can control your surge domain.                   |\n| `github_token`  | Used to create Pull Request comment, requires `pull-requests` permission set to `write`. Possible value: `secrets.GITHUB_TOKEN`.  | [`github.token`](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow) |\n| `build`         | Build scripts to run before deploy.                                                                                               | `npm install` \u003cbr\u003e `npm run build`                                                                                                       |\n| `dist`          | Dist folder deployed to [surge.sh](https://surge.sh/).                                                                            | `public`                                                                                                                                 |\n| `failOnError`   | Set `failed` if a deployment throws error. If not set, fallback to the `FAIL_ON__ERROR` environment variable.                     | `false`                                                                                                                                  |\n| `teardown`      | Determines if the preview instance will be torn down on PR close.                                                                 | `false`                                                                                                                                  |\n\n## 📤 Outputs\n\n- `preview_url`: The url for the related PR preview.\n\n## 💝 Who is using it?\n\n- [ant-design/ant-design-pro](https://github.com/ant-design/ant-design-pro)\n- [ant-design/pro-components](https://github.com/ant-design/pro-components)\n- [ant-design/ant-design-mini](https://github.com/ant-design/ant-design-mini)\n- [ant-design/pro-chat](https://github.com/ant-design/pro-chat)\n- [ant-design/pro-flow](https://github.com/ant-design/pro-flow)\n- [ant-design/pro-editor](https://github.com/ant-design/pro-editor)\n- [ant-design/antd-style](https://github.com/ant-design/antd-style)\n- [ant-design/cssinjs](https://github.com/ant-design/cssinjs)\n- [antvis/antvis.github.io](https://github.com/antvis/antvis.github.io)\n- [antvis/gatsby-theme-antv](https://github.com/antvis/gatsby-theme-antv)\n- [antvis/g2](https://github.com/antvis/g2)\n- [antvis/g2plot](https://github.com/antvis/g2plot)\n- [antvis/g6](https://github.com/antvis/g6)\n- [antvis/x6](https://github.com/antvis/x6)\n- [antvis/AVA](https://github.com/antvis/AVA)\n- [antvis/GPT-Vis](https://github.com/antvis/GPT-Vis)\n- [antvis/L7Plot](https://github.com/antvis/L7Plot)\n- [react-component/color-picker](https://github.com/react-component/color-picker)\n- [react-component/tour](https://github.com/react-component/tour)\n- [react-component/portal](https://github.com/react-component/portal)\n- [react-component/segmented](https://github.com/react-component/segmented)\n- [umijs/dumi](https://github.com/umijs/dumi)\n- [alibaba/hooks](https://github.com/alibaba/hooks)\n- [youzan/vant](https://github.com/youzan/vant)\n- [didi/cube-ui](https://github.com/didi/cube-ui)\n- [didi/mand-mobile](https://github.com/didi/mand-mobile)\n- [jdf2e/nutui](https://github.com/jdf2e/nutui)\n- [gocrane/crane](https://github.com/gocrane/crane)\n- [lijinke666/react-music-player](https://github.com/lijinke666/react-music-player)\n- [NeteaseYanxuan/OSSA](https://github.com/NeteaseYanxuan/OSSA)\n- [NSFI/ppfish-components](https://github.com/NSFI/ppfish-components)\n- [catppuccin/website](https://github.com/catppuccin/website)\n- [openaps/AndroidAPSdocs](https://github.com/openaps/AndroidAPSdocs)\n- [robotframework/robotframework.github.com](https://github.com/robotframework/robotframework.github.com)\n- [debezium/debezium.github.io](https://github.com/debezium/debezium.github.io)\n- [ant-design-colorful/ant-design-colorful](https://github.com/ant-design-colorful/ant-design-colorful)\n- [iambumblehead/react-dropdown-now](https://github.com/iambumblehead/react-dropdown-now)\n- [libwebp-wasm/gif2webp](https://github.com/libwebp-wasm/gif2webp)\n- [libwebp-wasm/img2webp](https://github.com/libwebp-wasm/img2webp)\n\n## 🙏 Thanks to\n\n- [jwalton/gh-find-current-pr](https://github.com/jwalton/gh-find-current-pr)\n- [marocchino/sticky-pull-request-comment](https://github.com/marocchino/sticky-pull-request-comment)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fafc163%2Fsurge-preview","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fafc163%2Fsurge-preview","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fafc163%2Fsurge-preview/lists"}