Skip to content
Merged
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
22 changes: 22 additions & 0 deletions .github/.gitversion.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
mode: ContinuousDeployment
tag-prefix: v
increment: None
commit-message-incrementing: Enabled
major-version-bump-message: '^(feat|fix|chore|ci|docs|test)(\(.+\))?\!:.*'
minor-version-bump-message: '^feat(\(.+\))?:.*'
patch-version-bump-message: '^(fix|ci)(\(.+\))?:.*'
branches:
main:
is-main-branch: true
increment: None
feature:
label: alpha
regex: ^(feat(ure)?|(bug)?fix)[\/-](?<BranchName>.+)
increment: None
release:
label: rc
regex: ^releases?[\/-](?<BranchName>.+)
increment: None
ignore:
sha: []
merge-message-formats: {}
42 changes: 42 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: pr
on:
pull_request:
branches:
- main

jobs:
validate:
name: validate
runs-on: ubuntu-latest
steps:
- uses: hwrok/print-workflow-data@v1

- name: checkout
uses: actions/checkout@v6

- name: pnpm
uses: pnpm/action-setup@v4
with:
version: 10

- name: node
uses: actions/setup-node@v6.2.0
with:
node-version-file: '.nvmrc'
cache: 'pnpm'

- name: pnpm install
id: install-deps
run: pnpm install

- name: check - tests
if: always() && steps.install-deps.outcome == 'success'
run: pnpm test

- name: check - formatting
if: always() && steps.install-deps.outcome == 'success'
run: pnpm format

- name: check - spelling
if: always() && steps.install-deps.outcome == 'success'
run: pnpm spellcheck
112 changes: 112 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name: release

on:
workflow_dispatch:
workflow_call:
outputs:
version:
description: 'version'
value: ${{ jobs.release.outputs.version }}
tag:
description: 'version tag'
value: ${{ jobs.release.outputs.tag }}

concurrency:
group: release

jobs:
release:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.compute_version.outputs.semVer }}
tag: ${{ steps.check_tag.outputs.tag }}
permissions:
contents: write

steps:
- uses: hwrok/print-workflow-data@v1

- name: checkout
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: install gitversion
uses: gittools/actions/gitversion/setup@v4
with:
versionSpec: '6.3.x'
preferLatestVersion: true

- name: compute version
id: compute_version
uses: gittools/actions/gitversion/execute@v4
with:
configFilePath: .github/.gitversion.yml

- run: echo "version:${{ steps.compute_version.outputs.semVer }}"

- name: check tag
id: check_tag
run: |
tag="v${{ steps.compute_version.outputs.semVer }}"
echo "tag=$tag" >> $GITHUB_OUTPUT
if git rev-parse "$tag" >/dev/null 2>&1; then
echo "::warning::Tag $tag already exists — skipping release."
else
echo "should_tag=true" >> $GITHUB_OUTPUT
fi

- name: configure git
if: steps.check_tag.outputs.should_tag
run: |
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config user.name "github-actions[bot]"

- name: create tag
if: steps.check_tag.outputs.should_tag
run: |
tag="${{ steps.check_tag.outputs.tag }}"
git tag "$tag"
git push origin "$tag"

- name: changelog
if: steps.check_tag.outputs.should_tag
id: changelog
run: |
CURRENT_TAG="${{ steps.check_tag.outputs.tag }}"
PREV_TAG=$(git tag --sort=-version:refname | grep -v "$CURRENT_TAG" | head -n 1)

if [ -z "$PREV_TAG" ]; then
PREV_TAG=$(git rev-list --max-parents=0 HEAD)
fi

CHANGELOG=$(git log --pretty="- %s (%h)" "$PREV_TAG".."$CURRENT_TAG")

DELIMITER=$(openssl rand -hex 16)
echo "CHANGELOG<<$DELIMITER" >> $GITHUB_ENV
echo "$CHANGELOG" >> $GITHUB_ENV
echo "$DELIMITER" >> $GITHUB_ENV

- name: update tracking tag
if: steps.check_tag.outputs.should_tag
run: |
SEMVER="${{ steps.compute_version.outputs.semVer }}"
MAJOR_VERSION=$(echo $SEMVER | cut -d '.' -f 1)
TRACKING_TAG="v$MAJOR_VERSION"

git tag -f $TRACKING_TAG
git push origin $TRACKING_TAG -f

- name: create release
if: steps.check_tag.outputs.should_tag
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.check_tag.outputs.tag }}
name: 'Release ${{ steps.check_tag.outputs.tag }}'
body: |
## Release ${{ steps.check_tag.outputs.tag }}

### Changes
${{ env.CHANGELOG }}
draft: false
prerelease: false
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
.claude
.idea
node_modules
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v24
10 changes: 10 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Package Managers
package-lock.json
pnpm-lock.yaml
yarn.lock
bun.lock
bun.lockb

# Miscellaneous
/static/
.terraform/
9 changes: 9 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"useTabs": false,
"singleQuote": true,
"quoteProps": "consistent",
"trailingComma": "all",
"printWidth": 100,
"plugins": [],
"overrides": []
}
83 changes: 83 additions & 0 deletions action.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/env bash
set +eo pipefail

# formats a value for display
# json objects -> aligned key:value table
# other json -> pretty-printed
# non-json / n/a -> raw
format_value() {
local value="$1"
if [ "$value" = "n/a" ] || [ -z "$value" ]; then
echo "n/a"
return
fi
if ! command -v jq >/dev/null 2>&1; then
echo "$value"
return
fi
if echo "$value" | jq -e 'type == "object"' >/dev/null 2>&1; then
echo "$value" | jq -r '
(keys | map(length) | max) as $w |
to_entries[] |
"\(.key + (" " * ($w - (.key | length)))) : \(.value | if type == "string" then . elif type == "null" then "" else tojson end)"
'
return
fi
if echo "$value" | jq -e '.' >/dev/null 2>&1; then
echo "$value" | jq '.'
return
fi
echo "$value"
}

# prints a labeled section with a colored box header
print_section() {
local title="$1"
local body="$2"
local color=92 # bright green
local bar_len=$(( ${#title} + 2 ))
local bar
bar="$(printf '─%.0s' $(seq 1 $bar_len))"
printf '\e[1;%sm┌%s┐\e[0m\n' "$color" "$bar"
printf '\e[1;%sm│ %s │\e[0m\n' "$color" "$title"
printf '\e[1;%sm└%s┘\e[0m\n' "$color" "$bar"
printf '%s\n' "$body"
}

if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
is_default_branch="false"
is_default_target="false"
[ "$GITHUB_REF_NAME" = "$DEFAULT_BRANCH" ] && is_default_branch="true"
[ "$GITHUB_BASE_REF" = "$DEFAULT_BRANCH" ] && is_default_target="true"

github_context_body=$(cat <<EOF
github.actor : $GITHUB_ACTOR
github.triggering_actor : $TRIGGERING_ACTOR
github.workflow : $GITHUB_WORKFLOW
github.workflow_ref : $GITHUB_WORKFLOW_REF
github.run_id : $GITHUB_RUN_ID
github.run_number : $GITHUB_RUN_NUMBER
github.run_attempt : $GITHUB_RUN_ATTEMPT
github.event_name : $GITHUB_EVENT_NAME
github.event.action : $EVENT_ACTION
github.base_ref : $GITHUB_BASE_REF
github.head_ref : $GITHUB_HEAD_REF
is_default_branch : $is_default_branch
is_default_target : $is_default_target
github.ref : $GITHUB_REF
github.ref_name : $GITHUB_REF_NAME
github.sha : $GITHUB_SHA
EOF
)

print_section "github context" "$github_context_body"
print_section "matrix context" "$(format_value "$MATRIX_CONTEXT")"
print_section "job context" "$(format_value "$JOB_CONTEXT")"
print_section "runner context" "$(format_value "$RUNNER_CONTEXT")"
print_section "caller inputs" "$(format_value "$CALLER_INPUTS")"
print_section "caller needs" "$(format_value "$CALLER_NEEDS")"
print_section "caller vars" "$(format_value "$CALLER_VARS")"
print_section "extras" "$(format_value "$EXTRAS")"

exit 0
fi
55 changes: 9 additions & 46 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
name: Print Workflow Data
description: "prints select github context for debugging purposes"
description: 'prints select github context for debugging purposes'

branding:
color: 'green'
icon: 'bar-chart-2'

inputs:
caller-inputs:
description: '`caller-inputs: {{ toJSON(inputs) }}`'
description: '`caller-inputs: ${{ toJSON(inputs) }}`'
required: false
default: ''
caller-needs:
description: '`caller-needs: {{ toJSON(needs) }}`'
description: '`caller-needs: ${{ toJSON(needs) }}`'
required: false
default: ''
caller-vars:
description: 'pass via `caller-vars: {{ toJSON(vars) }}` (generally safe unless secrets have been mismanaged)'
description: 'pass via `caller-vars: ${{ toJSON(vars) }}` (generally safe unless secrets have been mismanaged)'
required: false
default: ''
extras:
Expand All @@ -24,57 +24,20 @@ inputs:
default: ''

runs:
using: "composite"
using: 'composite'
steps:
- name: Print Workflow Data
shell: bash
continue-on-error: true
env:
TRIGGERING_ACTOR: ${{ github.triggering_actor }}
EVENT_ACTION: ${{ github.event.action }}
DEFAULT_BRANCH: ${{ github.event && github.event.repository && github.event.repository.default_branch }}
MATRIX_CONTEXT: ${{ matrix && toJSON(matrix) || 'n/a' }}
JOB_CONTEXT: ${{ toJSON(job) }}
RUNNER_CONTEXT: ${{ toJSON(runner) }}
CALLER_INPUTS: ${{ inputs.caller-inputs != '' && inputs.caller-inputs || 'n/a' }}
CALLER_NEEDS: ${{ inputs.caller-needs != '' && inputs.caller-needs || 'n/a' }}
CALLER_VARS: ${{ inputs.caller-vars != '' && inputs.caller-vars || 'n/a' }}
EXTRAS: ${{ inputs.extras != '' && inputs.extras || 'n/a' }}
DEFAULT_BRANCH: ${{ github.event && github.event.repository && github.event.repository.default_branch }}
run: |
print_section() {
local title="$1"
local body="$2"
local color=92 # bright green
local bar_len=$(( ${#title} + 2 ))
echo -e "\e[1;${color}m┌$(printf '─%.0s' $(seq 1 $bar_len))┐\e[0m"
echo -e "\e[1;${color}m│ ${title} │\e[0m"
echo -e "\e[1;${color}m└$(printf '─%.0s' $(seq 1 $bar_len))┘\e[0m"
echo -e "$body"
}

github_context_body=$(cat <<EOF
github.actor : ${{ github.actor }}
github.triggering_actor : ${{ github.triggering_actor }}
github.workflow : ${{ github.workflow }}
github.workflow_ref : ${{ github.workflow_ref }}
github.run_id : ${{ github.run_id }}
github.run_number : ${{ github.run_number }}
github.run_attempt : ${{ github.run_attempt }}
github.event_name : ${{ github.event_name }}
github.event.action : ${{ github.event.action }}
github.base_ref : ${{ github.base_ref }}
github.head_ref : ${{ github.head_ref }}
is_default_branch : ${{ github.ref_name == env.DEFAULT_BRANCH }}
is_default_target : ${{ github.base_ref == env.DEFAULT_BRANCH }}
github.ref : ${{ github.ref }}
github.ref_name : ${{ github.ref_name }}
github.sha : ${{ github.sha }}
EOF
)

print_section "github context" "$github_context_body"
print_section "matrix context" "$MATRIX_CONTEXT"
print_section "job context" "$JOB_CONTEXT"
print_section "runner context" "$RUNNER_CONTEXT"
print_section "caller inputs" "$CALLER_INPUTS"
print_section "caller needs" "$CALLER_NEEDS"
print_section "caller vars" "$CALLER_VARS"
print_section "extras" "$EXTRAS"
run: ${{ github.action_path }}/action.sh
Loading