Generate a verifiable professional portfolio from your GitHub history — README section, JSON Resume, PDF CV, and SVG stat cards — in a single workflow run.
Privacy & scope. Uses only
public_repoandread:user. No data leaves your runner.
Add a workflow to your profile repository (<your-login>/<your-login>):
# .github/workflows/portfolio.yml
name: Portfolio
on:
schedule:
- cron: '17 4 * * *' # daily refresh
workflow_dispatch:
permissions:
contents: write
jobs:
refresh:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: AbdullahBakir97/PortfolioCraft@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}Then in your README.md, drop the markers wherever you want generated content:
<!-- PORTFOLIOCRAFT:START -->
<!-- PORTFOLIOCRAFT:END -->That's it. The next run inserts your stack, top projects, activity summary, and a generation receipt between the markers.
Permissions. The default
commit: truemakes the action push regenerated artifacts back to your repo. That requirespermissions: contents: writeon the calling workflow (already shown in the snippet above). Without it,git pushreturns 403 and the run fails. Setcommit: falseif you only want artifacts as workflow outputs.
| Artifact | Path (default) | Source |
|---|---|---|
| README block | README.md |
Eta templates per locale, between markers |
| JSON Resume | profile.json |
schemaVersion: "1.0.0" |
| PDF CV | cv.pdf |
@react-pdf/renderer |
| SVG cards | assets/cards/*.svg |
Satori + @resvg/resvg-js |
Each artifact is independent — set the matching path input to '' to skip it.
| Name | Default | Description |
|---|---|---|
token |
required | secrets.GITHUB_TOKEN is enough for public-repo data; PAT unlocks private signal. |
user |
token owner | GitHub login to profile. |
sections |
header,stack,projects,activity |
Comma-separated README sections in order. |
locale |
en |
Template locale. en and ar ship at launch. |
output-readme |
README.md |
README to update between markers. Empty string to skip. |
output-json |
profile.json |
JSON Resume output path. Empty string to skip. |
output-pdf |
cv.pdf |
PDF CV output path. Empty string to skip. |
output-svg-dir |
assets/cards |
Directory for stat cards. Empty string to skip. |
config-file |
.portfoliocraft.yml |
Optional YAML config to override defaults (filters, weights, sections). |
commit |
true |
Commit generated artifacts back to the repo on a non-dry-run. |
commit-message |
chore: refresh portfolio |
Commit message used when committing artifacts. |
dry-run |
false |
Run end-to-end without writing files or committing. |
explain |
false |
Print scoring/classification reasoning to the job log. |
| Name | Description |
|---|---|
readme-updated |
true if the README was changed by this run. |
json-path |
Path of the generated JSON Resume file. |
pdf-path |
Path of the generated PDF CV. |
cards-dir |
Directory containing generated SVG cards. |
summary |
One-line summary of the generated portfolio. |
Stack proficiency is computed as LOC × recency_decay × repo_maturity per language, then ranked and bucketed into proficiency tiers. Project significance excludes forks, archives, and tutorial-shaped repos by default; you can override the filter rules in .portfoliocraft.yml. Domain classification (Backend / Frontend / DevOps / ML / Mobile) uses a deterministic, weighted-keyword classifier over languages, topics, and dependency manifests.
Run with explain: true to see every weight, decision, and tie-break in the job log.
npx portfoliocraft generate --user AbdullahBakir97 --dry-run --explainSame engine, no Action runtime required.
A second mode surfaces eight self-awareness signals across your public footprint — stale repos, missing licenses, missing READMEs, missing tests, PR rot, bug debt, archived-but-active repos, and archive suggestions.
- uses: AbdullahBakir97/PortfolioCraft@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
mode: audit # 'portfolio' (default), 'audit', or 'both'
audit-output-md: audit.md
audit-output-json: audit.json
audit-fail-on: '' # '' | low | medium | high | criticalnpx portfoliocraft audit --user AbdullahBakir97 --md audit.md --json audit.jsonOutputs are deterministic: an idempotent Markdown report (between <!-- PORTFOLIOCRAFT-AUDIT:START --> markers if the path matches your README) and a Zod-validated JSON report (schemaVersion: "1.0.0") suitable for downstream tooling. Default mode: portfolio is unchanged from v0.1 — existing workflows keep working.
Full check catalog and configuration reference live at the docs site.
The original use case behind PortfolioCraft was "I needed a summary of my projects so I can edit my CV and write university applications." Summary mode ships that — three paste-ready Markdown outputs derived deterministically from your GitHub data:
| Output | Format | Use case |
|---|---|---|
summary-cv.md |
Compact CV section: header, skills tiers, selected projects, activity | Paste into your CV and edit |
summary-uni.md |
Narrative: learning trajectory, technical depth, scope of work | University motivation letters / personal statements |
summary-case-studies.md |
One section per top project: stack, scale, overview, topics | Portfolio decks, application supplements |
- uses: AbdullahBakir97/PortfolioCraft@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
mode: summary # or 'all' for portfolio + audit + summary
summary-format: all # cv | uni | case-studies | all
summary-projects-max: 6npx portfoliocraft summary --user AbdullahBakir97 --format allAll summary text is generated deterministically from your existing GitHub data — no LLM, no API key, no hosted backend. The output is intentionally a clean draft for you to edit, not polished prose.
# .portfoliocraft.yml
sections: [header, stack, projects, activity]
locale: en
filters:
exclude_archived: true
exclude_forks: true
exclude_topics: [tutorial, exercise]
weights:
loc: 0.5
recency: 0.3
maturity: 0.2
projects:
pinned_first: true
max: 6pnpm install
pnpm build # turbo run build across workspaces
pnpm test # vitest
pnpm bundle # ncc → packages/action/dist/index.js → dist/
pnpm verify # the full pre-push gate (lint + typecheck + test + bundle)The repo is a pnpm + Turborepo monorepo:
packages/action— thin Action entrypoint (consumes@actions/*)packages/core— framework-free engine (Octokit, ingestion, scoring, classification)packages/renderers— markdown / json-resume / pdf / svgpackages/cli—npx portfoliocraftapps/docs— Starlight site
Reports go to SECURITY.md. Builds are reproducible via actions/attest-build-provenance; SBOMs are generated on every release with anchore/sbom-action.
Apache-2.0. See LICENSE.