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
49 changes: 49 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Bug report
description: Report a reproducible problem in a Jungle Grid public repository.
title: "[Bug]: "
body:
- type: markdown
attributes:
value: |
Do not report security vulnerabilities here. Email security@junglegrid.dev instead.
- type: input
id: repository
attributes:
label: Repository or package
description: Which Jungle Grid repository, package, CLI, MCP server, or example is affected?
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behavior
validations:
required: true
- type: textarea
id: actual
attributes:
label: Actual behavior
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: Steps to reproduce
description: Include commands, configuration snippets without secrets, and minimal examples.
validations:
required: true
- type: textarea
id: environment
attributes:
label: Environment
description: Include OS, Node.js/runtime version, package version, MCP host, browser, or CLI details as relevant.
validations:
required: false
- type: textarea
id: logs
attributes:
label: Logs or screenshots
description: Remove API keys, tokens, job secrets, customer data, and private URLs before posting.
render: text
validations:
required: false
8 changes: 8 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
blank_issues_enabled: true
contact_links:
- name: Security vulnerability
url: mailto:security@junglegrid.dev
about: Please report vulnerabilities privately instead of opening a public issue.
- name: Jungle Grid documentation
url: https://junglegrid.dev/docs
about: Read product and platform documentation.
35 changes: 35 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Feature request
description: Suggest a focused improvement for a Jungle Grid public repository.
title: "[Feature]: "
body:
- type: markdown
attributes:
value: |
Do not include private credentials, customer data, or undisclosed security issues.
- type: textarea
id: problem
attributes:
label: Problem
description: What workflow or limitation should this improve?
validations:
required: true
- type: textarea
id: proposal
attributes:
label: Proposed solution
description: Describe the smallest useful change.
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives considered
validations:
required: false
- type: textarea
id: context
attributes:
label: Additional context
description: Link related issues, docs, or examples.
validations:
required: false
26 changes: 26 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
## Summary

## Type of Change

- [ ] Bug fix
- [ ] Feature
- [ ] Documentation
- [ ] CI, security, or maintenance

## Validation

- [ ] I ran the relevant tests/checks locally
- [ ] I updated documentation where needed
- [ ] Not applicable

## Security and Secrets

- [ ] This change does not commit secrets, private keys, tokens, or `.env` files
- [ ] This change does not expose secrets to pull requests from forks
- [ ] Security-sensitive behavior has been called out for maintainers

## Checklist

- [ ] The change is focused and easy to review
- [ ] New or changed behavior is covered by tests where practical
- [ ] CI is expected to pass
12 changes: 12 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
groups:
github-actions:
patterns:
- "*"
22 changes: 22 additions & 0 deletions .github/workflows/pr-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: PR CI

on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
static:
if: github.event_name != 'pull_request' || !github.event.pull_request.draft
uses: ./.github/workflows/reusable-static-pr-ci.yml
permissions:
contents: read
with:
working-directory: "."
141 changes: 141 additions & 0 deletions .github/workflows/reusable-node-pr-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
name: Reusable Node PR CI

on:
workflow_call:
inputs:
node-version:
description: Node.js version to install.
required: false
type: string
default: "20"
package-manager:
description: "Package manager to use: npm, pnpm, yarn, or bun."
required: true
type: string
working-directory:
description: Directory containing the package manifest and lockfile.
required: false
type: string
default: "."
run-lint:
description: Run npm/pnpm/yarn/bun lint script.
required: false
type: boolean
default: false
run-format:
description: Run npm/pnpm/yarn/bun format check script.
required: false
type: boolean
default: false
format-script:
description: Script name for formatting checks.
required: false
type: string
default: "format:check"
run-typecheck:
description: Run npm/pnpm/yarn/bun typecheck script.
required: false
type: boolean
default: false
run-tests:
description: Run npm/pnpm/yarn/bun test script.
required: false
type: boolean
default: false
run-build:
description: Run npm/pnpm/yarn/bun build script.
required: false
type: boolean
default: false

permissions:
contents: read

jobs:
node-pr-ci:
name: Node PR CI
runs-on: ubuntu-latest
timeout-minutes: 20
defaults:
run:
working-directory: ${{ inputs.working-directory }}

steps:
- name: Check out repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

- name: Validate package manager input
run: |
case "${{ inputs.package-manager }}" in
npm|pnpm|yarn|bun) ;;
*) echo "Unsupported package manager: ${{ inputs.package-manager }}" >&2; exit 1 ;;
esac

- name: Set up Node.js
if: inputs.package-manager != 'bun'
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: ${{ inputs.node-version }}
cache: ${{ inputs.package-manager }}
cache-dependency-path: |
${{ inputs.working-directory }}/package-lock.json
${{ inputs.working-directory }}/npm-shrinkwrap.json
${{ inputs.working-directory }}/pnpm-lock.yaml
${{ inputs.working-directory }}/yarn.lock

- name: Set up Node.js without dependency cache
if: inputs.package-manager == 'bun'
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: ${{ inputs.node-version }}

- name: Set up Bun
if: inputs.package-manager == 'bun'
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: latest

- name: Enable Corepack
if: inputs.package-manager == 'pnpm' || inputs.package-manager == 'yarn'
run: corepack enable

- name: Install dependencies
run: |
case "${{ inputs.package-manager }}" in
npm)
npm ci
;;
pnpm)
pnpm install --frozen-lockfile
;;
yarn)
if node -e "const p=require('./package.json'); process.exit(/^yarn@([2-9]|[1-9][0-9])\./.test(p.packageManager || '') ? 0 : 1)"; then
yarn install --immutable
else
yarn install --frozen-lockfile
fi
;;
bun)
bun install --frozen-lockfile
;;
esac

- name: Run lint
if: inputs.run-lint
run: ${{ inputs.package-manager }} run lint

- name: Run format check
if: inputs.run-format
run: ${{ inputs.package-manager }} run ${{ inputs.format-script }}

- name: Run typecheck
if: inputs.run-typecheck
run: ${{ inputs.package-manager }} run typecheck

- name: Run tests
if: inputs.run-tests
run: ${{ inputs.package-manager }} test

- name: Run build
if: inputs.run-build
run: ${{ inputs.package-manager }} run build
82 changes: 82 additions & 0 deletions .github/workflows/reusable-static-pr-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: Reusable Static PR CI

on:
workflow_call:
inputs:
working-directory:
description: Directory to validate.
required: false
type: string
default: "."
run-secret-scan:
description: Run TruffleHog verified secret scan.
required: false
type: boolean
default: true

permissions:
contents: read

jobs:
static-pr-ci:
name: Static PR CI
runs-on: ubuntu-latest
timeout-minutes: 15
defaults:
run:
working-directory: ${{ inputs.working-directory }}

steps:
- name: Check out repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0

- name: Validate JSON files
run: |
mapfile -t files < <(find . -path './.git' -prune -o -type f \( -name '*.json' -o -name '*.json.example' \) -print)
if [ "${#files[@]}" -eq 0 ]; then
echo "No JSON files found."
exit 0
fi
python3 -m json.tool "${files[@]}" > /dev/null

- name: Validate YAML files
run: |
mapfile -t files < <(find . -path './.git' -prune -o -type f \( -name '*.yml' -o -name '*.yaml' \) -print)
if [ "${#files[@]}" -eq 0 ]; then
echo "No YAML files found."
exit 0
fi
ruby -e 'require "yaml"; ARGV.each { |path| YAML.load_file(path) }' "${files[@]}"

- name: Validate shell syntax
run: |
mapfile -t files < <(find . -path './.git' -prune -o -type f \( -name '*.sh' -o -perm -111 \) -print)
if [ "${#files[@]}" -eq 0 ]; then
echo "No shell files found."
exit 0
fi
for file in "${files[@]}"; do
if head -n 1 "$file" | grep -Eq '^#!.*/(env +)?(ba)?sh'; then
bash -n "$file"
elif [ "${file##*.}" = "sh" ]; then
bash -n "$file"
fi
done

- name: Block committed dotenv/private key files
run: |
if find . -path './.git' -prune -o -type f \( -name '.env' -o -name '.env.*' -o -name '*.pem' -o -name '*.key' \) ! -name '.env.example' -print | grep -q .; then
echo "Potential secret-bearing file detected. Commit examples only, such as .env.example." >&2
exit 1
fi

- name: Scan for verified secrets
if: inputs.run-secret-scan
uses: trufflesecurity/trufflehog@466da5b0bb161144f6afca9afe5d57975828c410 # v3.90.8
with:
path: ${{ inputs.working-directory }}
base: ${{ github.event.repository.default_branch }}
head: HEAD
extra_args: --only-verified
Loading
Loading