Skip to content
Open
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/test-repository-action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
uses: ./.
with:
username: ${{ github.repository_owner }}
output_path: ./trophy.svg
file: ./trophy.svg
token: ${{ secrets.GITHUB_TOKEN }}

- name: Verify SVG generated
Expand Down
37 changes: 33 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -578,9 +578,30 @@ given your username, (Enviroment Vars: See [env-example](env-example)).
Usage:

```bash
deno run --allow-net --allow-env --allow-read --allow-write ./render_svg.ts USERNAME OUTPUT_DIR THEME
deno run --allow-net --allow-env --allow-read --allow-write ./render_svg.ts USERNAME [options]

# Examples:
deno run --allow-net --allow-env --allow-read --allow-write ./render_svg.ts octocat
deno run --allow-net --allow-env --allow-read --allow-write ./render_svg.ts octocat -f profile/trophy.svg --theme classic
deno run --allow-net --allow-env --allow-read --allow-write ./render_svg.ts octocat --no-background --no-frame

# Help:
deno run --allow-net --allow-env --allow-read --allow-write ./render_svg.ts --help
```

Options:

- `-f, --file FILE` Output path (default: `./trophy.svg`)
- `-t, --theme THEME` Theme name (default: `default`)
- `-c, --cols N` Max columns (-1=auto, default: `-1`)
- `-r, --rows N` Max rows (default: `10`)
- `-s, --panel-size N` Panel size (default: `115`)
- `-mw, --margin-width N` Margin width (default: `10`)
- `-mh, --margin-height N` Margin height (default: `10`)
- `--no-background` Disable background
- `--no-frame` Disable frame
- `-h, --help` Show help

## Generate an svg inside Github CI (Workflow)

Using the provided github action you can easly generate the trophy inside an
Expand All @@ -590,12 +611,20 @@ have to manualy update rerun the action to update the file.
Usage:

```yaml
- name: Generate trophy
- name: Generate Profile Trophy
uses: Erik-Donath/github-profile-trophy@feature/generate-svg
with:
username: your-username
output_path: trophy.svg
token: ${{ secrets.GITHUB_TOKEN }}
username: your-username
file: trophy.svg
theme: classic
cols: -1
rows: 10
panel-size: 115
margin-width: 10
margin-height: 10
no-background: false
no-frame: false
```

# Contribution Guide
Expand Down
48 changes: 41 additions & 7 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,39 @@
name: Generate GitHub Profile Trophy SVG
description: Run the local generator script to produce an SVG.
inputs:
token:
description: "PAT or token to use for GitHub API"
required: true
username:
description: "GitHub username to generate the trophy for"
required: true
output_path:
file:
description: "Output path to write the SVG"
required: true
default: "trophy.svg"
token:
description: "PAT or token to use for GitHub API"
required: true
required: false
theme:
description: "Theme to use"
required: false
max-cols:
description: "Maximum of Cols"
required: false
max-rows:
description: "Maximum of Rows"
required: false
panel-size:
description: "Size of the Panel"
required: false
margin-width:
description: "Margin Width"
required: false
margin-height:
description: "Margin Height"
required: false
no-background:
description: "Disable background"
required: false
no-frame:
description: "Disable frame"
required: false
runs:
using: "composite"
steps:
Expand All @@ -24,4 +47,15 @@ runs:
env:
GITHUB_TOKEN1: ${{ inputs.token }}
run: |
deno run --allow-net --allow-env --allow-read --allow-write $GITHUB_ACTION_PATH/render_svg.ts "${{ inputs.username }}" "${{ inputs.output_path }}"
deno run --allow-net --allow-env --allow-read --allow-write \
$GITHUB_ACTION_PATH/render_svg.ts \
"${{ inputs.username }}" \
${{ inputs.file != '' && format('--file "{0}"', inputs.file) || '' }} \
${{ inputs.theme != '' && format('--theme "{0}"', inputs.theme) || '' }} \
${{ inputs['max-cols'] != '' && format('--cols "{0}"', inputs['max-cols']) || '' }} \
${{ inputs['max-rows'] != '' && format('--rows "{0}"', inputs['max-rows']) || '' }} \
${{ inputs['panel-size'] != '' && format('--panel-size "{0}"', inputs['panel-size']) || '' }} \
${{ inputs['margin-width'] != '' && format('--margin-width "{0}"', inputs['margin-width']) || '' }} \
${{ inputs['margin-height'] != '' && format('--margin-height "{0}"', inputs['margin-height']) || '' }} \
${{ inputs['no-background'] == 'true' && '--no-background' || '' }} \
${{ inputs['no-frame'] == 'true' && '--no-frame' || '' }}
128 changes: 102 additions & 26 deletions render_svg.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,105 @@
import "https://deno.land/x/dotenv@v0.5.0/load.ts";
import { parseArgs } from "https://deno.land/std@0.208.0/cli/parse_args.ts";
import { dirname } from "https://deno.land/std/path/mod.ts";

const username = Deno.args[0];
const outputPath = Deno.args[1] ?? "./assets/trophy.svg";
const themeName = Deno.args[2] ?? "default";
import { GithubApiService } from "./src/Services/GithubApiService.ts";
import { Card } from "./src/card.ts";
import { COLORS } from "./src/theme.ts";

if (!username) {
console.error(
"Usage: deno run --allow-net --allow-env --allow-read --allow-write ./render_svg.ts USERNAME [OUTPUT_PATH] [THEME]",
);
if (!Deno.env.get("GITHUB_TOKEN1")) {
console.error("Github Token is required!");
console.error("Create .env file with: GITHUB_TOKEN1=ghp_xxx");
Deno.exit(1);
}

import { GithubApiService } from "./src/Services/GithubApiService.ts";
import { Card } from "./src/card.ts";
import { COLORS } from "./src/theme.ts";
const args = parseArgs(Deno.args, {
boolean: ["help", "no-background", "no-frame"],
string: [
"file",
"theme",
"cols",
"rows",
"panel-size",
"margin-width",
"margin-height",
],
default: {
file: "./trophy.svg",
theme: "default",
cols: "-1",
rows: "10",
"panel-size": "115",
"margin-width": "10",
"margin-height": "10",
},
alias: {
h: "help",
f: "file",
t: "theme",
c: "cols",
r: "rows",
s: "panel-size",
mw: "margin-width",
mh: "margin-height",
},
});

if (args.help || args._.length === 0) {
console.log(`github-profile-trophy v0.0.0

Usage: deno run render_svg.ts USERNAME [options]

ENV: GITHUB_TOKEN1=ghp_xxx (required)

USERNAME: Github username

Options:
-f, --file FILE Output file (default: ./trophy.svg)
-t, --theme THEME Theme name (default: default)
-c, --cols N Max Columns (-1=auto, default: -1)
-r, --rows N Max Rows (default: 10)
-s, --panel-size N Panel size (default: 115)
-mw, --margin-width N Margin Width size (default: 10)
-mh, --margin-height N Margin Height size (default: 10)
--no-background Disable background
--no-frame Disable frame
-h, --help Show this help`);

Deno.exit(0);
}

function parseIntSafe(
value: string | undefined,
fallback: number,
name: string,
): number {
const val = value ?? String(fallback);
const num = parseInt(val, 10);
if (Number.isNaN(num)) {
console.error(`Invalid ${name}: "${val}"; Must be a number!`);
Deno.exit(2);
}
return num;
}

const [username] = args._ as string[];
const file = args.file as string;
const themeName = args.theme as string;
const maxColumn = parseIntSafe(args.cols, -1, "cols");
const maxRow = parseIntSafe(args.rows, 10, "rows");
const panelSize = parseIntSafe(args["panel-size"], 115, "panel-size");
const marginWidth = parseIntSafe(args["margin-width"], 10, "margin-width");
const marginHeight = parseIntSafe(args["margin-height"], 10, "margin-height");
const noBackground = args["no-background"] as boolean;
const noFrame = args["no-frame"] as boolean;

async function main() {
console.log("Starting trophy render...");
console.log("Username:", username);
console.log("Output path:", outputPath);
console.log("File:", file);
console.log("Theme:", themeName);

const svc = new GithubApiService();

const userInfoOrError = await svc.requestUserInfo(username);

if (
Expand All @@ -31,19 +108,11 @@ async function main() {
console.error(
"Failed to fetch user info. Check token, username and rate limits.",
);
Deno.exit(2);
Deno.exit(3);
}

const userInfo = userInfoOrError as any;

const panelSize = 115;
const maxRow = 10;
const maxColumn = -1; // auto
const marginWidth = 10;
const marginHeight = 10;
const noBackground = false;
const noFrame = false;

const card = new Card(
[],
[],
Expand All @@ -59,15 +128,22 @@ async function main() {
const svg = card.render(userInfo, theme);

try {
const dir = outputPath.replace(/\/[^/]+$/, "");
if (dir) await Deno.mkdir(dir, { recursive: true });
const dir = dirname(file);
if (dir && dir !== ".") {
await Deno.mkdir(dir, { recursive: true });
}
} catch {
console.error("Failed to create directory. No permission?");
Deno.exit(3);
Deno.exit(4);
}

await Deno.writeTextFile(outputPath, svg);
console.log(`Wrote ${outputPath}`);
try {
await Deno.writeTextFile(file, svg);
console.log(`Wrote ${file}`);
} catch {
console.error("Failed to write file. No permission?");
Deno.exit(5);
}
}

await main();
Loading