Thank you for your interest in contributing. Please read this guide before opening a pull request.
- Fork the repository by clicking the "Fork" button on GitHub.
- Clone your fork locally:
git clone https://github.com/<your-username>/workflow-metrics.git cd workflow-metrics - Create a branch for your change:
git checkout -b feat/my-feature # or git checkout -b fix/my-bug - Install dependencies and set up the project (see Setup below).
- Make your changes, following the coding standards.
- Test your changes locally (see Test below).
- Commit using Conventional Commits:
git commit -m "feat: add DORA metrics export to CSV" git commit -m "fix: resolve crash when repository has no workflow runs" - Push your branch to your fork:
git push origin feat/my-feature - Open a Pull Request against the
mainbranch of this repository. Fill in the PR template that appears automatically.
The CI pipeline will run lint, tests, and a build check on your PR. All checks must pass before the PR can be merged.
- Use Conventional Commits for commit messages — this drives automated versioning and changelog generation.
- Write strict TypeScript; avoid
any. - Keep server-side logic (GitHub API, Supabase, AI calls) in
src/lib/server/. Keep UI logic insrc/lib/components/and route files. Do not mix them. - Add or update tests for any logic change in
src/lib/server/orsrc/lib/utils.ts. - Maintain coverage thresholds: lines/functions/statements ≥ 80%, branches ≥ 70%.
- Update
README.mdif your change adds a feature or modifies existing behaviour.
- Node.js >= 24
- PNPM >= 10
- A Supabase project (for auth and database)
- A GitHub OAuth App (for GitHub login)
pnpm install
Copy the example environment file and fill in your credentials:
cp .env.example .env
Required environment variables:
| Variable | Description |
|---|---|
PUBLIC_SUPABASE_URL |
Your Supabase project URL |
PUBLIC_SUPABASE_ANON_KEY |
Your Supabase anon key |
GITHUB_APP_ID |
GitHub App ID (for server-side API calls) |
GITHUB_APP_PRIVATE_KEY |
GitHub App private key |
MISTRAL_API_KEY |
Mistral API key (for AI optimization features) |
pnpm dev
The app will be available at http://localhost:5173.
pnpm build
pnpm test
pnpm lint
pnpm check
To run tests with coverage:
pnpm test:coverage
Coverage is enforced at: lines/functions/statements ≥ 80%, branches ≥ 70%.
On every pull request to main, GitHub Actions runs:
- Lint: ESLint (TypeScript + Svelte)
- Test: Vitest with v8 coverage, uploaded to Codecov
- Build: SvelteKit build check
- Security:
pnpm audit --audit-level=high(fails on high or critical vulnerabilities) - Dependency Review: Scans dependency manifest changes for known vulnerabilities
Workflow file: .github/workflows/pull-request.yml.
All GitHub Actions workflows use step-security/harden-runner with egress blocking to mitigate supply chain attacks. Only explicitly allowed endpoints can be reached.
What it does:
- Monitors network egress to detect unauthorized outbound calls
- Tracks file integrity to detect tampering
- Monitors process activity for suspicious behavior
Workflows protected:
- .github/workflows/pull-request.yml — CI checks
- .github/workflows/release.yml — Release automation
- .github/workflows/deploy.yml — Cloudflare Pages deployment
- .github/workflows/codeql-analysis.yml — CodeQL static analysis
- .github/workflows/scorecard.yml — OpenSSF Scorecard
Audit results and insights are available at the Step Security dashboard.
Releases are automated with Semantic Release. On every push to main:
- Test job runs: lint, unit tests (Vitest), and build.
- Release job runs only if tests pass: Semantic Release analyzes commits, bumps the version, updates
package.jsonandCHANGELOG.md, pushes a release commit, and creates a GitHub release. - Deploy job runs if a new release was created: builds and deploys to Cloudflare Pages.
Use Conventional Commits so versions and changelog are derived from commit messages:
feat: ...→ minor release (e.g. 1.1.0)fix: ...→ patch (e.g. 1.0.1)feat!: ...orfix!: ...→ major (e.g. 2.0.0)docs:,chore:, etc. → no release (included in changelog when relevant)
Workflow: .github/workflows/release.yml.
Deployment to Cloudflare Pages is triggered automatically after a successful release. The build adapter is @sveltejs/adapter-cloudflare.
Required Secrets (in GitHub repository settings):
| Secret | Description |
|---|---|
CLOUDFLARE_API_TOKEN |
Cloudflare API token with Pages deploy permissions |
CLOUDFLARE_ACCOUNT_ID |
Cloudflare account ID |
SUPABASE_URL |
Supabase project URL (production) |
SUPABASE_ANON_KEY |
Supabase anon key (production) |
GITHUB_APP_ID |
GitHub App ID (production) |
GITHUB_APP_PRIVATE_KEY |
GitHub App private key (production) |
MISTRAL_API_KEY |
Mistral API key (production) |
- Framework: Svelte 5 + SvelteKit 2
- Styling: Tailwind CSS 4
- UI Components: bits-ui, lucide-svelte, layerchart
- Auth & Database: Supabase (GitHub OAuth + PostgreSQL)
- GitHub API: @octokit/rest
- AI: Vercel AI SDK + @ai-sdk/mistral
- Graph Visualization: @xyflow/svelte
- Deployment: Cloudflare Pages via @sveltejs/adapter-cloudflare + Wrangler
- Testing: Vitest 3 + v8 coverage + Codecov
- Linting: ESLint 9 +
eslint-plugin-svelte+typescript-eslint - Packaging: PNPM 10