Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
node-version: "22"
cache: npm

- name: Install dependencies
Expand Down
58 changes: 58 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Deploy portfolio to GitHub Pages

on:
schedule:
- cron: "23 5 * * 1"
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: engineer-profile-pages
cancel-in-progress: true

jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.pages.outputs.base_url }}
env:
GITHUB_TOKEN: ${{ github.token }}
steps:
- name: Check out source
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm

- name: Install dependencies
run: npm ci

- name: Install Chromium
run: npx playwright install chromium --with-deps

- name: Refresh portfolio
run: npm run refresh -- --config engineer-profile.config.json

- name: Stage deployment files
run: node dist/index.js deploy

- name: Configure GitHub Pages
id: pages
uses: actions/configure-pages@v5

- name: Upload site artifact
uses: actions/upload-pages-artifact@v3
with:
path: output/

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
2 changes: 1 addition & 1 deletion .github/workflows/refresh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
node-version: "22"
cache: npm

- name: Install dependencies
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20
22
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Local checks

Use Node.js 20 or newer.
Use Node.js 22 or newer.

```bash
npm ci
Expand Down
151 changes: 140 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# EngineerProfile

EngineerProfile builds a local engineering portfolio from public repository data.
It stores repository metadata, commits, releases, privacy settings, and preview
paths in SQLite. It publishes a static site from these records.
It stores repository metadata, commits, releases, privacy settings, and preview paths in SQLite.
It publishes a static site from these records.

## Value

Expand All @@ -11,6 +11,10 @@ paths in SQLite. It publishes a static site from these records.
- Build release notes from releases or conventional commits.
- Capture repeatable project previews with Playwright.
- Hide projects and redact author emails before publication.
- Choose a built-in theme or supply your own CSS.
- Surface commit-diff totals on every project card.
- Publish an RSS feed of release and commit signals.
- Stage the site for GitHub Pages deployment.
- Run one configured refresh from a scheduled workflow.

The fixture demo runs without secrets and without network access.
Expand All @@ -27,31 +31,39 @@ flowchart LR
D --> L[Changelog]
D --> P[Privacy]
D --> S[Playwright]
D --> F[RSS feed]
L --> W[Publisher]
P --> W
S --> W
T[Theme] --> W
W --> O[Static output]
F --> O
O --> K[Deploy]
K --> U[GitHub Pages]
```

| Area | Responsibility |
| --- | --- |
| `engineer-profile.config.json` | Store owner, presentation, refresh, paths, and privacy settings. |
| `engineer-profile.config.json` | Store owner, presentation, theme, refresh, deployment, paths, and privacy settings. |
| `src/config/` | Validate checked-in JSON and merge safe defaults. |
| `src/refresh/` | Coordinate ingest, best-effort capture, and static publishing. |
| `src/refresh/` | Coordinate ingest, best-effort capture, static publishing, and deployment staging. |
| `src/ingest/` | Fetch public GitHub data and map it to records. |
| `src/db/` | Store projects, commits, changelogs, and audit events. |
| `src/changelog/` | Prefer release notes and fall back to commit groups. |
| `src/privacy/` | Hide projects and block sensitive commit messages. |
| `src/preview/` | Capture fixed viewport screenshots with Playwright. |
| `src/theme/` | Provide built-in themes and merge custom CSS. |
| `src/feed/` | Render a deterministic RSS feed from changelog entries. |
| `src/publish/` | Render HTML, changelog files, and preview assets. |
| `src/deploy/` | Stage the published site for a deployment platform. |
| `fixtures/` | Provide deterministic demo data and local preview pages. |

The refresh command runs each stage in a fixed order.
If a preview fails, the command reports the skip and keeps the rest of the snapshot.

## Setup

Use Node.js 20 or newer.
Use Node.js 22 or newer.

```bash
npm ci
Expand All @@ -68,7 +80,7 @@ Both directories are ignored by Git.
## Configuration

`engineer-profile.config.json` is the checked-in source for scheduled refreshes.
It sets the GitHub owner, site presentation, repository limit, paths, and privacy controls.
It sets the GitHub owner, site presentation, repository limit, paths, privacy controls, and feed settings.

The loader accepts repository limits from 1 through 100.
It rejects malformed values before network access.
Expand All @@ -94,6 +106,93 @@ npm run refresh
Do not put a token in repository files.
Use `.env.example` as a variable reference.

## Themes

The site uses a theme for presentation.
Pick a theme by name in the config file.
Run `npm run themes` to list the built-in themes.

The default theme is `midnight`.

| Theme | Appearance |
| --- | --- |
| `midnight` | Dark interface with blue and mint accents. |
| `paper` | Light interface with serif type and warm paper tones. |
| `terminal` | Monospace interface inspired by a terminal emulator. |

Set the theme by name:

```json
{ "theme": "paper" }
```

Set a custom theme with an object:

```json
{ "theme": { "name": "studio", "customCss": "themes/studio.css" } }
```

The loader rejects unknown theme names unless you provide a custom CSS file.
The publisher appends your CSS after the built-in stylesheet.
Use CSS variables to override the base palette and fonts.
Start from a built-in theme, then override the variables you need.

## Deployment

`engineer-profile` can stage a site for GitHub Pages.
Set the deployment platform in the config file.
The publisher writes a `.nojekyll` file for GitHub Pages.
It writes a `CNAME` file when you configure a custom domain.

```json
{
"deployment": {
"platform": "github-pages",
"cname": "engineering.example.com"
}
}
```

Stage the published site with a command:

```bash
npm run deploy
```

The `deploy` workflow publishes the site to GitHub Pages.
It runs on a schedule and on manual dispatch.
Enable the Pages feature in the repository settings first.
The workflow does not manage repository settings.

## RSS feed

The publisher writes an RSS feed at publish time.
The feed contains the latest changelog entry for each visible project.
Entries link back to their release pages or commit records.

Set the feed channel in the config file:

```json
{
"feed": {
"enabled": true,
"limit": 20,
"description": "Release notes from public repositories.",
"siteUrl": "https://engineering.example.com"
}
}
```

The feed is enabled by default.
The limit caps the number of items.
The description falls back to the portfolio tagline.
The site URL sets the canonical channel link.
Without a site URL, the publisher uses the deployment domain or the repository homepage.

Feed output is deterministic.
The same snapshot produces the same `feed.xml`.
The page head links to the feed with an `alternate` tag.

## Sample output

The fixture set contains `signal-router` and `metrics-kit`.
Expand All @@ -106,12 +205,22 @@ Captured demo-engineer-signal-router.
Captured demo-engineer-metrics-kit.
Published 2 projects to output/index.html.
Copied 2 available preview screenshots.
Wrote output/feed.xml with 2 entries.
Open output/index.html in a browser.
```

The site shows project facts, source links, changelog previews, and screenshots.
The site shows project facts, source links, changelog previews, screenshots, and diff totals.
The totals come from fixture fields and stored commit records.

With GitHub Pages configured, the deploy command adds one line:

```text
Published 2 projects to output/index.html.
Copied 2 available preview screenshots.
Wrote output/feed.xml with 2 entries.
Staged .nojekyll for github-pages.
```

## Commands

Build before direct CLI commands.
Expand All @@ -122,8 +231,10 @@ Build before direct CLI commands.
| `npm run ingest -- octocat --limit 3` | Load public repository evidence. |
| `npm run ingest -- --fixture` | Load fixture records only. |
| `npm run capture -- --fixture` | Capture local fixture pages. |
| `npm run publish` | Rebuild the site from SQLite. |
| `npm run refresh` | Run configured ingest, capture, and publish stages. |
| `npm run publish` | Rebuild the site and RSS feed from SQLite. |
| `npm run deploy` | Publish, write the feed, and stage deployment files. |
| `npm run themes` | List built-in themes. |
| `npm run refresh` | Run configured ingest, capture, publish, and feed stages. |
| `node dist/index.js status` | Show visibility and recent operations. |
| `npm test` | Run deterministic unit and integration tests. |
| `npm run typecheck` | Validate TypeScript types. |
Expand All @@ -148,8 +259,12 @@ Sensitive commit messages are skipped before storage.

Each project stores a repository URL and its last pushed timestamp.
Each stored commit keeps its SHA, message first line, date, and source URL.
Each stored commit also keeps its line additions, line deletions, change total, and file count.
Each release keeps its tag, notes, date, and source URL.

The site shows the commit diff totals on each project card.
Commit-based changelog bullets carry per-commit diff markers.

The site displays visible projects only.
It links project cards to repositories.
It links release notes to their release pages.
Expand All @@ -158,8 +273,12 @@ It records local operations in an audit table.
## CI and test status

The regular CI workflow runs typecheck, build, tests, the fixture demo, and artifact upload.
It runs on Node.js 22.
The scheduled refresh workflow runs each Monday and supports manual dispatch.
It uploads the generated site as a workflow artifact.
The deploy workflow publishes the site to GitHub Pages.
Tests run in a single forked process.
This keeps native modules and Playwright stable on shared runners.

The test suite covers these core behaviors:

Expand All @@ -168,6 +287,10 @@ The test suite covers these core behaviors:
- Release-first changelog generation.
- SQLite upserts and changelog replacement.
- Privacy filtering and email redaction.
- Theme resolution and custom CSS overlays.
- Deployment staging for GitHub Pages.
- Commit diff totals and per-commit diff markers.
- Deterministic RSS feed output.
- Fixture ingestion and static publishing.
- Configured refresh orchestration.
- Release source links.
Expand Down Expand Up @@ -198,15 +321,21 @@ The fixture pipeline provides deterministic data for repeatable checks.
- Capture failures are reported and do not stop publishing.
- Publishing creates local files. It does not deploy them.
- Scheduled runs upload artifacts. They do not commit generated output.
- GitHub Pages deployment needs the Pages feature enabled in the repository settings.
- Custom themes must define the CSS variables the base stylesheet expects.
- Diff totals cover the tracked commit window only.
- The RSS feed contains visible projects only.
- Feed links fall back to the repository homepage without a site URL.

## Roadmap

| Release | Status | Scope |
| --- | --- | --- |
| v0.1 | Complete | Fixture demo, GitHub ingest, changelog, capture, publish, and privacy controls. |
| v0.2 | Complete | Checked-in configuration, coordinated refresh command, and scheduled artifact workflow. |
| v0.3 | Next | Custom themes and deployment adapters. |
| v0.4 | Later | Commit-diff summaries and an RSS feed. |
| v0.3 | Complete | Custom themes and deployment adapters. |
| v0.4 | Complete | Commit-diff summaries and an RSS feed. |
| v0.5 | Next | Project detail pages and a machine-readable JSON export. |

## License

Expand Down
7 changes: 7 additions & 0 deletions engineer-profile.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
"repositoryLimit": 5,
"dataDir": "data",
"outputDir": "output",
"theme": "midnight",
"deployment": {
"platform": "github-pages"
},
"feed": {
"enabled": true
},
"privacy": {
"hiddenProjects": [],
"redactEmails": true,
Expand Down
Loading
Loading