{"id":33314493,"url":"https://github.com/technance-foundation/vercel-to-github-relay","last_synced_at":"2026-05-12T12:05:13.185Z","repository":{"id":324750218,"uuid":"1098313344","full_name":"technance-foundation/vercel-to-github-relay","owner":"technance-foundation","description":"🧪 Webhook Relay linking Vercel deployments with GitHub’s E2E test pipeline","archived":false,"fork":false,"pushed_at":"2025-11-17T16:30:42.000Z","size":51,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-17T18:13:31.578Z","etag":null,"topics":["api","e2e","microservice","playwright","relay","tests","vercel"],"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/technance-foundation.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":".github/CODEOWNERS","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":"2025-11-17T14:30:15.000Z","updated_at":"2025-11-17T16:31:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/technance-foundation/vercel-to-github-relay","commit_stats":null,"previous_names":["technance-foundation/vercel-to-github-relay"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/technance-foundation/vercel-to-github-relay","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technance-foundation%2Fvercel-to-github-relay","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technance-foundation%2Fvercel-to-github-relay/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technance-foundation%2Fvercel-to-github-relay/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technance-foundation%2Fvercel-to-github-relay/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/technance-foundation","download_url":"https://codeload.github.com/technance-foundation/vercel-to-github-relay/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technance-foundation%2Fvercel-to-github-relay/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":285240542,"owners_count":27137943,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-19T02:00:05.673Z","response_time":65,"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":["api","e2e","microservice","playwright","relay","tests","vercel"],"created_at":"2025-11-19T12:00:46.422Z","updated_at":"2026-05-12T12:05:13.178Z","avatar_url":"https://github.com/technance-foundation.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# **Vercel → GitHub Relay**\n\nThis service connects Vercel preview deployments with GitHub’s E2E test pipeline.\n\nGitHub Actions can run tests -- but they don’t know _when_ a preview deployment is actually ready.\nThis Relay fills that gap.\n\nWhenever Vercel finishes building a preview deployment, the Relay:\n\n1. Verifies the webhook signature\n2. Figures out the commit / branch involved\n3. Resolves E2E project configuration\n4. Creates an E2E Check Run on GitHub\n5. Triggers the E2E workflow with the correct inputs\n6. Lets the E2E Test Runner handle everything else\n\nIt’s a small piece of glue, but it's what makes E2E checks feel like a natural part of your pull-request flow.\n\n---\n\n## **GitHub App Required**\n\nThe Relay uses a GitHub App to create check runs and trigger workflows.\nIf you don’t have one yet, follow the setup guide here:\n\n👉 **[GitHub App Setup Guide](./GITHUB_APP_SETUP.md)**\n\n---\n\n## **Environment variables**\n\nTo run correctly, the Relay needs:\n\n### **From GitHub App**\n\n| Variable             | Description                                 |\n| -------------------- | ------------------------------------------- |\n| `GH_APP_ID`          | The GitHub App ID                           |\n| `GH_APP_PRIVATE_KEY` | Multiline private key (Relay normalizes it) |\n| `GH_OWNER`           | GitHub org/user owning the repo             |\n| `GH_REPO`            | Repo where the E2E workflow lives           |\n\n### **From Vercel**\n\n| Variable                | Description                      |\n| ----------------------- | -------------------------------- |\n| `VERCEL_WEBHOOK_SECRET` | Secret used to validate webhooks |\n\n---\n\n## **🚨 Workflow Filename Matters**\n\n\u003e [!IMPORTANT]\n\u003e The Relay triggers a workflow by filename:\n\u003e **`e2e.yaml`**\n\nIf you rename this file, update the Relay constant:\n\n```ts\nconst GH_WORKFLOW_FILE = \"e2e.yaml\";\n```\n\nA mismatched name will cause E2E checks to remain stuck in \"Queued\" forever.\n\n---\n\n## **E2E Project Configuration**\n\nThe Relay supports per-project configuration via:\n\n```txt\n.github/e2e-projects.json\n```\n\n### ✅ Recommended: Use Vercel Project ID\n\nEach Vercel webhook includes a stable project ID:\n\n```ts\npayload.project.id;\n```\n\nYou should use this as the primary key in your config, since:\n\n- Project names can change\n- IDs are stable and reliable\n- Avoids accidental mismatches\n\n---\n\n### Example\n\n```json\n{\n    \"projects\": {\n        \"prj_jWLGA9cpGatUCCf4kVLC5V44kuDt\": {\n            \"project\": \"midnight\",\n            \"workingDirectory\": \"apps/midnight\",\n            \"testCommand\": \"pnpm run test:e2e\",\n            \"checkName\": \"Midnight\"\n        }\n    }\n}\n```\n\n---\n\n### Fields\n\n| Field              | Description                     |\n| ------------------ | ------------------------------- |\n| `project`          | Value passed to the workflow    |\n| `workingDirectory` | Where tests should run          |\n| `testCommand`      | Command used to run E2E tests   |\n| `checkName`        | Optional label for GitHub check |\n\n---\n\n### How it works\n\n- The Relay first tries to match using:\n    - `payload.project.id` (recommended)\n\n- If not found, it falls back to:\n    - `deployment.name`\n\nResolution logic:\n\n```ts\nprojects[projectId] ?? projects[deploymentName];\n```\n\n---\n\n### Fallback behavior\n\nIf no config exists, the Relay defaults to:\n\n```ts\n{\n  project: deploymentName,\n  workingDirectory: `apps/${deploymentName}`,\n  testCommand: \"pnpm run test:e2e\",\n  checkName: deploymentName,\n}\n```\n\nThis ensures zero breaking changes and keeps setup friction low.\n\n---\n\n## **How the Relay works (high level)**\n\nEvery time a preview deployment succeeds on Vercel:\n\n1. **Vercel sends a `deployment.succeeded` webhook**\n   The Relay verifies authenticity and parses deployment details.\n\n2. **It resolves the correct Git SHA**\n   Either from deployment metadata or by asking GitHub.\n\n3. **It resolves project configuration**\n   From `.github/e2e-projects.json` (project ID first, name fallback).\n\n4. **It creates a GitHub Check Run**\n   So the PR instantly shows:\n   _\"E2E Tests -- \u003cproject\u003e\"_\n\n5. **It dispatches the E2E workflow**\n   Passing along:\n    - `url`\n    - `project`\n    - `check_run_id`\n    - `working_directory`\n    - `test_command`\n\n6. **The workflow takes over**\n   The `e2e-test-runner` action handles setup, testing, and updating the check status.\n\n---\n\n## **Development**\n\nRun locally with:\n\n```sh\npnpm install\npnpm dev\n```\n\n### Notes\n\n#### 1. Vercel won’t forward real webhooks to localhost\n\nYou can simulate them manually:\n\n```sh\ncurl -X POST http://localhost:3000/api/vercel-to-github-success-deployment \\\n  -H \"x-vercel-signature: \u003chmac\u003e\" \\\n  -d @test-payload.json\n```\n\n#### 2. Your GitHub App must be installed on the correct repo\n\nWithout it, the Relay can’t create check runs.\n\n#### 3. The private key must keep its newlines\n\nThe Relay automatically restores `\\n` if your environment strips them.\n\n---\n\n## **Deploying**\n\nThis project is already wired for Vercel:\n\n```sh\nvercel deploy --prod\n```\n\nOnce deployed, configure your Vercel project to send `deployment.succeeded` webhooks to:\n\n```\n/api/vercel-to-github-success-deployment\n```\n\n---\n\n## **Local Testing (Simulating Vercel Webhooks)**\n\nVercel does not forward real webhooks to localhost, so the project includes a helper script to simulate a full `deployment.succeeded` event.\n\n### Useful for testing:\n\n- Webhook signature verification\n- Git SHA resolution\n- Project config resolution (project ID first, deployment name fallback)\n- GitHub App check run creation\n- Workflow dispatching logic\n\n---\n\n### Usage\n\n```sh\n./test-webhook.sh \u003cdeployment-name\u003e \u003cpreview-url\u003e [branch] [project-id]\n```\n\n- `\u003cdeployment-name\u003e` -- Vercel deployment name (`deployment.name`)\n- `\u003cpreview-url\u003e` -- preview deployment URL\n- `[branch]` -- optional (defaults to `main`)\n- `[project-id]` -- optional Vercel project ID (`payload.project.id`)\n\n---\n\n### Examples\n\n#### Basic\n\n```sh\n./test-webhook.sh portal https://portal-git-main-abc123.vercel.app\n```\n\n#### Custom branch\n\n```sh\n./test-webhook.sh portal https://portal-git-feat-login.vercel.app feat/login\n```\n\n#### Local Relay\n\n```sh\nexport WEBHOOK_ENDPOINT=\"http://localhost:3000/api/vercel-to-github-success-deployment\"\nexport VERCEL_WEBHOOK_SECRET=\"dev-secret\"\n\n./test-webhook.sh portal http://localhost:3000\n```\n\n#### With project ID (recommended)\n\n```sh\n./test-webhook.sh midnight https://midnight-git-main-abc123.vercel.app main prj_jWLGA9cpGatUCCf4kVLC5V44kuDt\n```\n\n---\n\nThe script sends a **fully valid** Vercel webhook envelope, computes the correct **HMAC SHA1 signature**, and posts it to your Relay -- just like Vercel does in production.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechnance-foundation%2Fvercel-to-github-relay","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftechnance-foundation%2Fvercel-to-github-relay","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechnance-foundation%2Fvercel-to-github-relay/lists"}