Skip to content

AbdullahBakir97/PortfolioCraft

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

PortfolioCraft

Marketplace CI CodeQL License: Apache-2.0 Node 20 LTS

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_repo and read:user. No data leaves your runner.

Quickstart (60s)

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: true makes the action push regenerated artifacts back to your repo. That requires permissions: contents: write on the calling workflow (already shown in the snippet above). Without it, git push returns 403 and the run fails. Set commit: false if you only want artifacts as workflow outputs.

What gets generated

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.

Inputs

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.

Outputs

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.

How scoring works

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.

Local CLI

npx portfoliocraft generate --user AbdullahBakir97 --dry-run --explain

Same engine, no Action runtime required.

Audit mode (v0.2)

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 | critical
npx portfoliocraft audit --user AbdullahBakir97 --md audit.md --json audit.json

Outputs 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.

Summary mode (v0.4) — CV + university applications

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: 6
npx portfoliocraft summary --user AbdullahBakir97 --format all

All 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.

Configuration file

# .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: 6

Development

pnpm 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 / svg
  • packages/clinpx portfoliocraft
  • apps/docs — Starlight site

Security

Reports go to SECURITY.md. Builds are reproducible via actions/attest-build-provenance; SBOMs are generated on every release with anchore/sbom-action.

License

Apache-2.0. See LICENSE.

About

Generate a verifiable professional portfolio from your GitHub history — README block, JSON Resume, PDF CV, and stat cards. GitHub Action + CLI.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors