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
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ updates:
directory: /
schedule:
interval: weekly
cooldown:
default-days: 7
labels:
- dependencies
ignore:
Expand All @@ -12,6 +14,8 @@ updates:
directory: /
schedule:
interval: weekly
cooldown:
default-days: 7
labels:
- dependencies
- github-actions
1 change: 1 addition & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@
## Release

- [ ] A root Changeset is included when the change affects a published package.
- [ ] If a package change intentionally needs no release, the `skip-changeset` label is applied with maintainer agreement.
- [ ] No package-specific release workflow or prerelease metadata was added.
31 changes: 31 additions & 0 deletions .github/workflows/link-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Documentation links

on:
pull_request:
paths:
- README.md
- apps/web/**
- packages/*/README.md
- .lycheeignore
schedule:
- cron: "23 9 * * 1"
workflow_dispatch:

permissions:
contents: read

jobs:
links:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Check documentation links
uses: lycheeverse/lychee-action@e7477775783ea5526144ba13e8db5eec57747ce8 # v2
with:
args: >-
--verbose --no-progress --max-retries 3 --retry-wait-time 2 --timeout 20 --exclude-mail --exclude '^/' --accept 200,206,301,302,307,308,429 README.md 'apps/web/**/*.md' 'apps/web/**/*.mdx' 'packages/*/README.md'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37 changes: 37 additions & 0 deletions .github/workflows/pr-metadata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: PR metadata

on:
pull_request_target:
types: [opened, reopened, synchronize, ready_for_review, labeled, unlabeled]

concurrency:
group: pr-metadata-${{ github.event.pull_request.number }}-${{ github.event.action }}-${{ github.event.label.name || 'none' }}
cancel-in-progress: ${{ github.event.action == 'synchronize' }}

permissions:
contents: read
issues: write
pull-requests: read

jobs:
metadata:
if: >-
(github.event.action != 'labeled' && github.event.action != 'unlabeled') || github.event.label.name == 'skip-changeset'
runs-on: ubuntu-latest
steps:
- name: Checkout trusted default-branch automation
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.event.repository.default_branch }}
persist-credentials: false
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: 1.4.2
- name: Label pull request and validate Changeset coverage
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: bun scripts/pr-metadata.ts
75 changes: 75 additions & 0 deletions .github/workflows/workflow-security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: Workflow security

on:
pull_request:
paths:
- .github/workflows/**
- .github/actions/**
- .github/dependabot.yml
- .github/zizmor.yml
push:
branches: [main]
paths:
- .github/workflows/**
- .github/actions/**
- .github/dependabot.yml
- .github/zizmor.yml

permissions:
contents: read

jobs:
actionlint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: actionlint
uses: raven-actions/actionlint@3d39aea434753780c3b3d4a1a31c854b4dbf49d7 # v2
with:
version: 1.7.11
cache: false
shellcheck: true
pyflakes: false

zizmor:
runs-on: ubuntu-latest
steps:
- name: Checkout trusted security configuration
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.event.repository.default_branch }}
path: trusted
persist-credentials: false
- name: Checkout workflow changes for analysis
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ github.event.pull_request.head.sha || github.sha }}
path: source
persist-credentials: false
- name: Select trusted zizmor configuration
id: zizmor-config
shell: bash
env:
IS_FORK_PR: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }}
run: |
if [[ -f trusted/.github/zizmor.yml ]]; then
echo "path=trusted/.github/zizmor.yml" >> "$GITHUB_OUTPUT"
elif [[ "$IS_FORK_PR" == "true" ]]; then
echo "::error::The trusted default branch has no zizmor configuration; refusing to use fork-provided configuration."
Comment thread
mynameistito marked this conversation as resolved.
exit 1
else
echo "::warning::The trusted branch has no zizmor configuration yet; using same-repository configuration for this bootstrap run."
echo "path=source/.github/zizmor.yml" >> "$GITHUB_OUTPUT"
Comment thread
mynameistito marked this conversation as resolved.
fi
- name: zizmor
uses: zizmorcore/zizmor-action@cc914d7f3750a2d13d75c7f184a1060aa0e9d482 # v0.6.4
with:
advanced-security: false
annotations: true
config: ${{ steps.zizmor-config.outputs.path }}
inputs: source/.github
version: 1.30.1
16 changes: 16 additions & 0 deletions .github/zizmor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# These findings are limited to existing, intentionally reviewed workflow
# patterns. Keep the ignores line-specific so new findings remain visible.
rules:
dangerous-triggers:
ignore:
- deploy-preview.yml:3
- deploy.yml:3
# Required for fork-safe labeling; this workflow checks out only the trusted default branch.
- pr-metadata.yml:3
excessive-permissions:
ignore:
- deploy-preview.yml:20
- deploy-preview.yml:21
adhoc-packages:
ignore:
- release.yml:35
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@

## Changesets

Create Changesets at the root with `bun run changeset-add -- force-input|usage-limits patch|minor|major "summary"`.
Create Changesets at the root with `bun run changeset-add -- docs|force-input|usage-limits patch|minor|major "summary"`. Meaningful plugin changes and documentation-site content changes require a matching Changeset. Tests, package-local scripts, and listed development-only metadata/configuration changes are exempt. Apply `skip-changeset` only for a justified non-release change and with maintainer agreement.

## Pull request automation

PR metadata automation labels changed components from file paths and package names in changed Changesets, and reconciles size labels on every update. Documentation link checks run for relevant edits and weekly. Workflow security scans run when Actions or Dependabot configuration changes.

## Testing

Expand Down
3 changes: 3 additions & 0 deletions packages/opencode-force-input/scripts/test-package.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { checkPackageTarball } from "../../../scripts/check-package-tarball.ts";

const tuiEntrypoint = new URL("../dist/index.mjs", import.meta.url);
const tuiModule = await import(tuiEntrypoint.href);
const tuiPlugin = tuiModule.default;
Expand All @@ -13,3 +15,4 @@ if (!hasValidTuiPlugin) {
}

console.log(`Package smoke test passed: ${tuiPlugin.id}`);
await checkPackageTarball("packages/opencode-force-input");
30 changes: 30 additions & 0 deletions packages/opencode-usage-limits/__tests__/package-tarball.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { describe, expect, it } from "vitest";

import { isUnexpectedPackagePath } from "../../../scripts/package-tarball-helpers.ts";

describe("package tarball paths", () => {
it("rejects package source, test, and script directories", () => {
expect(isUnexpectedPackagePath("src/index.ts")).toBeTruthy();
expect(isUnexpectedPackagePath("__tests__/plugin.test.ts")).toBeTruthy();
expect(isUnexpectedPackagePath("scripts/test-package.ts")).toBeTruthy();
});

it("rejects root-level test and build directories", () => {
expect(isUnexpectedPackagePath("test/fixtures/sample.ts")).toBeTruthy();
expect(isUnexpectedPackagePath("tests/fixtures/sample.ts")).toBeTruthy();
expect(isUnexpectedPackagePath("spec/plugin.spec.ts")).toBeTruthy();
expect(isUnexpectedPackagePath("build/output.js")).toBeTruthy();
});

it("rejects root-level test and build scripts", () => {
expect(isUnexpectedPackagePath("test-package.ts")).toBeTruthy();
expect(isUnexpectedPackagePath("build.ts")).toBeTruthy();
expect(isUnexpectedPackagePath("plugin.test.ts")).toBeTruthy();
});

it("allows intended root package files and build output", () => {
expect(isUnexpectedPackagePath("README.md")).toBeFalsy();
expect(isUnexpectedPackagePath("dist/index.mjs")).toBeFalsy();
expect(isUnexpectedPackagePath("usage-limits.schema.json")).toBeFalsy();
});
});
Loading
Loading