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
61 changes: 61 additions & 0 deletions .github/workflows/oss-maintainer-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: OSS Maintainer Pull Request

on:
pull_request_target:
types: [opened, edited, synchronize, reopened]
pull_request:
types: [opened, synchronize, reopened]

permissions: {}

jobs:
metadata:
if: github.event_name == 'pull_request_target'
permissions:
contents: read
issues: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Checkout the trusted default branch only
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
ref: ${{ github.event.repository.default_branch }}
persist-credentials: false
- name: Plan metadata actions
run: >-
python3 automation/oss_maintainer.py plan
--event "$GITHUB_EVENT_PATH"
--event-name pull_request
--policy automation/maintenance-policy.json
--now "${{ github.event.pull_request.updated_at }}"
--output "$RUNNER_TEMP/pr-plan.json"
- name: Optionally enrich the deterministic plan
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: >-
python3 automation/oss_maintainer.py enrich
--plan "$RUNNER_TEMP/pr-plan.json"
--event "$GITHUB_EVENT_PATH"
--policy automation/maintenance-policy.json
--output "$RUNNER_TEMP/pr-plan-enriched.json"
- name: Apply allowlisted metadata actions
env:
GH_TOKEN: ${{ github.token }}
run: >-
python3 automation/oss_maintainer.py apply
--plan "$RUNNER_TEMP/pr-plan-enriched.json"
--policy automation/maintenance-policy.json
--repository "$GITHUB_REPOSITORY"
--target-number "${{ github.event.pull_request.number }}"

checks:
if: github.event_name == 'pull_request'
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
persist-credentials: false
- run: python3 -m unittest discover -s automation/tests -v
31 changes: 31 additions & 0 deletions .github/workflows/oss-maintainer-schedule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: OSS Maintainer Schedule Report

on:
schedule:
- cron: "17 3 * * 1"
workflow_dispatch:

permissions: {}

jobs:
report:
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
persist-credentials: false
- name: Build maintenance report
run: >-
python3 automation/oss_maintainer.py plan
--event "$GITHUB_EVENT_PATH"
--event-name schedule
--policy automation/maintenance-policy.json
--now "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
--output "$RUNNER_TEMP/maintenance-report.json"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: oss-maintenance-report
path: ${{ runner.temp }}/maintenance-report.json
if-no-files-found: error
45 changes: 45 additions & 0 deletions .github/workflows/oss-maintainer-triage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: OSS Maintainer Issue Triage

on:
issues:
types: [opened, edited, reopened]

permissions: {}

jobs:
triage:
permissions:
contents: read
issues: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
ref: ${{ github.event.repository.default_branch }}
persist-credentials: false
- name: Plan issue actions
run: >-
python3 automation/oss_maintainer.py plan
--event "$GITHUB_EVENT_PATH"
--event-name issues
--policy automation/maintenance-policy.json
--now "${{ github.event.issue.updated_at }}"
--output "$RUNNER_TEMP/issue-plan.json"
- name: Optionally enrich the deterministic plan
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: >-
python3 automation/oss_maintainer.py enrich
--plan "$RUNNER_TEMP/issue-plan.json"
--event "$GITHUB_EVENT_PATH"
--policy automation/maintenance-policy.json
--output "$RUNNER_TEMP/issue-plan-enriched.json"
- name: Apply allowlisted issue actions
env:
GH_TOKEN: ${{ github.token }}
run: >-
python3 automation/oss_maintainer.py apply
--plan "$RUNNER_TEMP/issue-plan-enriched.json"
--policy automation/maintenance-policy.json
--repository "$GITHUB_REPOSITORY"
--target-number "${{ github.event.issue.number }}"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
._*
__pycache__/
*.pyc
.worktrees/
30 changes: 30 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Contributing

Thank you for improving Codex Project Commander and its maintenance tooling. Keep each contribution scoped, review the affected policy or workflow contract before changing it, and include tests for behavior changes.

## Automation boundary

Automated replies are limited to low-risk, policy-allowlisted labels and comments. They are not endorsements, approvals, or merge decisions. Every pull request, issue decision, policy change, workflow change, and release still requires human review by a maintainer.

Do not submit changes that expand a workflow's permissions, run untrusted contributor code in a privileged job, expose Secrets, bypass idempotency markers, or make stale closure opt-out. Protected actions—including merging or approving pull requests, enabling workflows, changing repository settings or permissions, creating Secrets, publishing releases, and deleting branches or source—remain maintainer decisions outside this contribution process.

## Before opening a pull request

1. Keep generated files, credentials, and unrelated formatting changes out of the patch.
2. Update the relevant English and Chinese Skill documentation together when their shared policy boundary changes.
3. Run the applicable local tests. For the maintenance tooling, run:

```bash
python3 -m unittest discover -s automation/tests -v
```

4. When changing either maintenance Skill, validate both packages:

```bash
python3 path/to/quick_validate.py skills/automate-oss-maintenance
python3 path/to/quick_validate.py skills/automate-oss-maintenance-zh
```

5. Explain the behavior, validation evidence, and any remaining external state that cannot be observed locally.

Report suspected vulnerabilities through the route described in [SECURITY.md](SECURITY.md); do not place sensitive details in a public issue.
15 changes: 15 additions & 0 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,21 @@ OpenAI still recommends environment variables and prohibits embedding keys in cl
└── project-commander-zh/ # 中文 SKILL
```

## Automated OSS maintenance

This repository includes two independently installable maintenance Skills. Choose the edition that matches the working language:

| Edition | Skill path |
| --- | --- |
| English | `skills/automate-oss-maintenance` |
| Chinese | `skills/automate-oss-maintenance-zh` |

The maintenance plan is deterministic and policy-based through `automation/maintenance-policy.json`, so it works without an API key. Optional OpenAI enrichment reads only the repository Secret named `OPENAI_API_KEY`; configure it only when a maintainer chooses to use that optional enrichment.

The workflow files in this repository are local configuration. A maintainer must separately verify whether they have been committed, pushed, and enabled. Permissions are split by responsibility: issue triage and trusted-default-branch PR metadata may make only policy-allowlisted labels or comments; untrusted PR checks are content-read-only and receive no Secret; the scheduled job only builds a maintenance report. Automation does not merge or approve PRs, create releases, change repository settings or permissions, create Secrets, or delete branches or source.

See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution rules and [SECURITY.md](SECURITY.md) for the private vulnerability-reporting status.

## Official references

- [OpenAI Codex Agent Skills](https://developers.openai.com/codex/skills/)
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,21 @@ OpenAI 官方仍建议 API Key 使用环境变量、不得放入客户端或仓
└── token-governance.md
```

## 自动化开源维护

仓库包含两份可独立安装的开源维护技能;请选择与工作语言相符的一份:

| 版本 | 技能目录 |
| --- | --- |
| English | `skills/automate-oss-maintenance` |
| 中文版 | `skills/automate-oss-maintenance-zh` |

该维护方案先用 `automation/maintenance-policy.json` 做确定性规划,未配置 API Key 时仍可运行。可选的 OpenAI 增强只读取仓库 Secret `OPENAI_API_KEY`;只有维护者决定启用该可选增强时才应配置它。

随仓库提供的工作流文件是本地配置,是否已提交、推送和启用需要由维护者另行核实。权限按职责拆分:Issue 分类和受信任默认分支上的 PR 元数据处理只可执行策略允许的标签或评论;不可信 PR 检查仅有只读内容权限且不接触 Secret;定时任务只生成维护报告。自动化不会合并或批准 PR、创建 Release、修改仓库设置/权限、创建 Secret,或删除分支与源码。

贡献规则见 [CONTRIBUTING.md](CONTRIBUTING.md),私密漏洞报告状态见 [SECURITY.md](SECURITY.md)。

## 官方资料

- [OpenAI Codex Agent Skills](https://developers.openai.com/codex/skills/)
Expand Down
13 changes: 13 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Security policy

## Reporting vulnerabilities

GitHub Private Vulnerability Reporting is the intended private reporting route for this repository. Its enablement cannot be verified from the local repository evidence available here, so publication remains blocked until a maintainer enables and verifies it in GitHub.

Until that verification is complete, do not include vulnerability details, credentials, private keys, access tokens, or reproduction steps in a public issue. Do not invent an alternate reporting channel from local repository contents. A maintainer must publish and verify a private route before inviting reports through it.

## Automation safeguards

The local maintenance policy treats security-labelled work as protected and prevents ordinary automated comments for it. The optional `OPENAI_API_KEY` is a repository Secret name for optional enrichment; it must not be committed to files, test fixtures, logs, or documentation examples containing a real value.

Local workflow and policy files do not prove GitHub configuration, repository permissions, Secret values, or private-reporting availability. Verify those states in the repository settings before making a security-operation decision.
14 changes: 14 additions & 0 deletions automation/fixtures/issue-opened.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"delivery_id": "issue-opened-001",
"event_name": "issues",
"action": "opened",
"issue": {
"number": 12,
"title": "Broken example crashes",
"body": "The example crashes after startup.",
"labels": [],
"updated_at": "2026-07-17T00:00:00Z"
},
"repository": {"full_name": "example/oss-project"},
"context": {"existing_markers": []}
}
13 changes: 13 additions & 0 deletions automation/fixtures/pull-request-opened.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"delivery_id": "pull-request-opened-001",
"event_name": "pull_request",
"action": "opened",
"pull_request": {
"number": 34,
"title": "Improve docs",
"body": "Adds an installation example.",
"labels": []
},
"repository": {"full_name": "example/oss-project"},
"context": {"existing_markers": []}
}
7 changes: 7 additions & 0 deletions automation/fixtures/scheduled-run.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"delivery_id": "schedule-001",
"event_name": "schedule",
"action": "scheduled",
"repository": {"full_name": "example/oss-project"},
"context": {"existing_markers": []}
}
22 changes: 22 additions & 0 deletions automation/maintenance-policy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"version": 1,
"allowed_actions": ["add_label", "comment", "report", "close_waiting_issue"],
"label_rules": [
{"label": "bug", "keywords": ["bug", "error", "broken", "crash"]},
{"label": "documentation", "keywords": ["docs", "readme", "documentation"]},
{"label": "enhancement", "keywords": ["feature", "request", "enhancement"]},
{"label": "question", "keywords": []},
{"label": "needs-review", "keywords": []}
],
"required_issue_sections": ["reproduction", "environment"],
"markers": {"request_details": "oss-maintainer:request-details:v1"},
"protected_labels": ["security", "do-not-close"],
"max_mutations_per_run": 2,
"stale": {
"enabled": false,
"minimum_days": 30,
"required_label": "waiting-for-author",
"excluded_labels": ["security", "do-not-close"]
},
"ai": {"enabled": false, "model": "gpt-5.6"}
}
Loading