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
36 changes: 19 additions & 17 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ The project especially values:
- accessibility and native-editor UI improvements;
- concise documentation and diagnostics.

Discuss large features or architecture changes in an issue before investing in
an implementation. The project intentionally keeps a narrow submodule-only
scope.
Discuss large features or architecture changes in an issue before starting
work. The project stays focused on Git-hosted UPM packages managed through
Unity's native Package Manager; it is not a general-purpose Git client.

## Development Prerequisites

Expand Down Expand Up @@ -72,22 +72,25 @@ behavior.
- Keep runtime code out of the package; this is an editor-only tool.
- Preserve Windows, macOS, and Linux behavior.
- Never evaluate user input through a shell.
- Keep mutations restricted to direct `Packages/com.author.package` paths.
- Restrict submodule filesystem changes to validated direct
`Packages/<reverse-domain-name>` children, and guard UPM manifest changes
independently.
- Do not store credentials or run installers without the user's explicit
confirmation.
- Avoid implicit network or repository mutations during editor startup.
- Prefer explicit state, actionable errors, and rollback over optimistic UI.
- When a mutation fails, roll back only state the package owns, preserve
recovery evidence otherwise, and explain the next safe action.
- Keep public APIs minimal; most implementation types should remain `internal`.
- Add tests for parsing, state transitions, validation, and regressions.

## Test Before Opening a Pull Request

Run the license-free repository checks:
Run the checks that do not require a Unity license:

```bash
python3 .github/scripts/validate_repository.py
npx --yes markdownlint-cli2@0.23.0 "**/*.md" "#Library" "#Temp"
npm pack --dry-run
npm pack --ignore-scripts --dry-run
```

In Unity:
Expand Down Expand Up @@ -130,17 +133,16 @@ the `PackageManagerCompatibility` category. After it passes, run the complete
`MartinCalander.GitSubmoduleManager.Editor.Tests` assembly because behavior and
state-transition coverage intentionally lives outside the compatibility subset.

Maintainers can also dispatch **Sanity Checks** with a reviewed full commit SHA
and an exact `unity_version` of `6000.3.22f1` or a `6000.5.*f1` final release.
Manual dispatch stages the same package revision and runs the full EditMode
assembly in that Editor; normal protected push runs remain pinned to the minimum
`6000.3.22f1` eligibility baseline. Unity 6000.4 is not a validated target.

CI runs license-free structure, Markdown, archive, and portability checks on
every pull request. Unity credentials are never exposed to pull-request code.
After reviewing a contribution, a maintainer can manually dispatch the
**Sanity Checks** workflow with the reviewed commit as its `ref` to run the
protected Unity compile and EditMode-test gate.
every pull request without exposing Unity credentials to pull-request code.
After reviewing a contribution, a maintainer can dispatch **Sanity Checks**
from protected `main` with the full commit SHA and an exact `unity_version` of
`6000.3.22f1` or `6000.5.0f1`. Those CI choices use reviewed, digest-pinned
GameCI images; additional `6000.5.*f1` final patches can be checked locally
before their image digest is added. The job stages that exact package revision
and runs the full EditMode assembly. Protected push runs remain pinned to the
minimum `6000.3.22f1` eligibility baseline. Unity 6000.4 is not a validated
target.

Branch protection requires the workflow's stable **Required sanity gate**,
which aggregates package validation and the complete Linux, macOS, and Windows
Expand Down
18 changes: 11 additions & 7 deletions .github/GOVERNANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ Decisions are evaluated in this order:
1. protect users and their repositories from data loss or unsafe mutations;
2. preserve compatibility across supported Unity versions, Windows, macOS,
and Linux;
3. keep the package editor-only and focused on Git submodules directly below
`Packages/`;
3. keep the package editor-only and focused on Git-backed UPM packages, with
editable submodules limited to direct children of `Packages/`;
4. maintain clear, testable, and reviewable code;
5. improve performance where it does not compromise correctness or clarity.

Expand Down Expand Up @@ -56,15 +56,19 @@ before opening the normal public discussion.

- Changes normally enter `main` through a pull request.
- Required CI checks must pass before merge.
- At least one maintainer approval is expected for code changes.
- Authors do not approve their own changes when another active maintainer is
- Code changes should receive an independent maintainer review when one is
available.
- When the project has only one active maintainer, the project lead may merge
after required CI passes and must record the verification performed in the
pull request.
- Authors do not approve their own changes.
- Force pushes to protected branches and rewriting published release tags are
not part of the normal workflow.

Repository administrators may bypass the normal process only to respond to a
security incident, restore a broken release or automation path, or recover the
repository. The reason should be documented afterward when disclosure is safe.
Repository administrators may otherwise bypass the normal process only to
respond to a security incident, restore a broken release or automation path, or
recover the repository. The reason should be documented afterward when
disclosure is safe.

## Releases

Expand Down
23 changes: 9 additions & 14 deletions .github/MAINTAINERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,15 @@ practical, the reason should be stated clearly.

## Becoming a Maintainer

Maintainers are appointed by the project lead based on sustained, constructive
participation. Useful signals include sound technical judgment, respectful
reviews, reliable follow-through, cross-platform awareness, and careful
handling of failure and security cases.

There is no required number of commits and no automatic promotion. Repository
permissions are granted gradually and should remain no broader than necessary.
Martin Calander appoints maintainers after sustained contributions demonstrate
sound technical judgment, reliable follow-through, cross-platform awareness,
and careful handling of Git, Unity, and security failures. There is no commit
quota. Repository permissions are granted gradually and remain no broader than
necessary.

## Inactivity and Removal

A maintainer may step down at any time. The project lead may move an inactive
maintainer to emeritus status, reduce permissions that are no longer needed, or
remove a maintainer for security, conduct, or trust reasons.

Before a planned departure, maintainers should transfer open security work,
release responsibilities, and access that would otherwise leave the project
without an accountable owner.
A maintainer may step down at any time. The project lead may reduce or remove
access that is no longer needed, including after prolonged inactivity or for
security, conduct, or trust reasons. Before leaving, a maintainer should hand
off open security reports, release work, and any access that only they control.
10 changes: 7 additions & 3 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ Describe the user-facing change and why it is needed.
- [ ] Unity compiles with no new warnings or errors.
- [ ] Focused EditMode tests pass.
- [ ] The changed workflow was tested manually.
- [ ] Relevant Windows, macOS, and Linux impact was considered.
- [ ] I tested every affected platform, or listed below any platform I could not
test.

List exact commands, Unity versions, operating systems, and any skipped checks.

## Safety and Compatibility

- [ ] Mutations remain restricted to direct packages under `Packages/`.
- [ ] No shell evaluation, credential storage, system installer, or implicit startup mutation was introduced.
- [ ] Submodule filesystem changes stay within validated direct
`Packages/<reverse-domain-name>` children.
- [ ] User input is not passed through a shell.
- [ ] No credential storage, system installer execution, or implicit startup
mutation was introduced.
- [ ] Documentation and `CHANGELOG.md` were updated when behavior changed.
- [ ] New Unity assets were imported and include generated `.meta` files.

Expand Down
40 changes: 24 additions & 16 deletions .github/RELEASING.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Releasing Git Submodule Manager

This guide is for maintainers publishing a GitHub and UPM release. Releases
follow [Semantic Versioning](https://semver.org/) and are produced by the
[Publish Release workflow](workflows/release.yml).
This guide is for maintainers publishing a GitHub release for the UPM package.
Releases follow [Semantic Versioning](https://semver.org/) and are produced by
the [Publish Release workflow](workflows/release.yml).

## Release Authority

Expand All @@ -25,9 +25,14 @@ Before enabling credentialed CI, configure two protected GitHub environments:

Do not store Unity credentials as general repository secrets. Set the repository
variable `UNITY_CI_ENABLED=true` only after `unity-ci` is protected. Protect
`main` from direct/force pushes, require pull-request review and sanity checks,
and add a tag protection rule for `v*` before publishing. These settings are
repository controls and cannot be enforced by workflow YAML alone.
`main` from direct and force pushes, require pull requests and sanity checks,
and require independent review when another maintainer is available. Add a tag
protection rule for `v*` before publishing. These settings are repository
controls and cannot be enforced by workflow YAML alone.

Keep the GameCI action and each release-matrix Editor image pinned to reviewed
commit and image digests. Adding another Unity patch to CI requires recording
its exact image digest in both workflows before it can become a release gate.

## Version Policy

Expand All @@ -46,23 +51,26 @@ The version in [`package.json`](../package.json) and the tag without its leading
1. Work from a clean branch based on the latest `main`.
2. Update `package.json` to the intended version.
3. Move relevant entries from **Unreleased** into a dated version section in
[`CHANGELOG.md`](../CHANGELOG.md).
[`CHANGELOG.md`](../CHANGELOG.md), remove any unpublished-version note, and
update its comparison links for the intended tag.
4. Confirm installation, compatibility, and troubleshooting documentation are
still accurate.
5. Run the repository checks:

```bash
python3 .github/scripts/validate_repository.py
npx --yes markdownlint-cli2@0.23.0 "**/*.md" "#Library" "#Temp"
npm pack --dry-run
npm pack --ignore-scripts --dry-run
```

6. In a clean Unity project, install the package from the exact release commit,
run `MartinCalander.GitSubmoduleManager.Editor.Tests` in EditMode, and exercise add, update,
and remove behavior.
run `MartinCalander.GitSubmoduleManager.Editor.Tests` in EditMode, then test
submodule and read-only installation, both eligible conversions, and
submodule removal.
7. Record any platform or Unity version that could not be tested in the release
pull request.
8. Merge the release pull request only after required checks and review pass.
8. Merge the release pull request only after required checks pass and the
applicable review policy is satisfied.

Fork pull requests never receive Unity credentials. A maintainer must inspect
the contribution and manually dispatch **Sanity Checks** with its reviewed,
Expand Down Expand Up @@ -101,9 +109,9 @@ Pushing the tag starts the Publish Release workflow. The workflow:
Pre-release SemVer tags are published as GitHub pre-releases.

The workflow can also be started manually for an existing tag. Manual dispatch
does not create or move a tag. Run the workflow itself from the same exact
protected tag that is supplied as its input so the protected `release`
environment evaluates the reviewed release ref:
does not create or move a tag. Start the workflow from the same protected tag
provided as its input so the `release` environment evaluates the reviewed
release ref:

```bash
gh workflow run release.yml --ref v2.0.0 -f tag=v2.0.0
Expand Down Expand Up @@ -134,8 +142,8 @@ Do not rewrite or reuse a published version or tag. If a release is defective:
1. document the impact;
2. prepare a new patch version;
3. repeat the normal validation and publication process;
4. mark the affected GitHub release as deprecated only when that context helps
users.
4. update the affected release notes to point users to the fixed version when
that context is useful.

For a security release, coordinate timing and disclosure through
[SECURITY.md](SECURITY.md).
16 changes: 8 additions & 8 deletions .github/REPOSITORY_SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ settings are not stored in Git and must be configured in GitHub.
## General

- [ ] Confirm the repository owner and default branch are correct.
- [ ] Add the description: `A safe, cross-platform Unity Editor workflow for managing Git submodules as UPM packages.`
- [ ] Add the description: `Manage Git-hosted UPM packages in Unity as editable submodules or read-only dependencies.`
- [ ] Add topics: `unity`, `unity-editor`, `upm`, `git`, `submodule`,
`package-manager`, `developer-tools`.
- [ ] Leave the social preview unset unless a human-designed, project-specific
image is available; do not use a generic generated banner.
- [ ] Use a project-specific social preview, or leave it unset.
- [ ] Confirm GitHub recognizes the MIT license.
- [ ] Enable Issues so the bundled forms become available.

Expand All @@ -19,8 +18,8 @@ settings are not stored in Git and must be configured in GitHub.
Protect `main` with:

- [ ] pull requests required before merging;
- [ ] at least one approving review;
- [ ] review from the package Code Owner required;
- [ ] one approving review and Code Owner review when a second active maintainer
is available;
- [ ] stale approvals dismissed when new commits are pushed;
- [ ] conversation resolution required;
- [ ] `Required sanity gate` required from the **Sanity Checks** workflow, with
Expand Down Expand Up @@ -54,9 +53,10 @@ Protect release tags with a `v*` tag ruleset:
- [ ] Enable immutable releases before publishing the first release.
- [ ] Enable GitHub private vulnerability reporting and keep the security email
in `.github/SECURITY.md` monitored as a fallback.
- [ ] Create the referenced labels (`needs-triage`, `support`, `dependencies`,
`automation`, `maintenance`, `feature`, and `fix`) before enabling Issues or
release automation, then confirm both issue forms can be submitted.
- [ ] Create the referenced labels (`needs-triage`, `support`, `bug`,
`enhancement`, `documentation`, `dependencies`, `automation`, `maintenance`,
`feature`, and `fix`) before enabling Issues or release automation, then
confirm all three issue forms can be submitted.

## Release

Expand Down
38 changes: 21 additions & 17 deletions .github/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

## Supported Versions

Security fixes are applied to the latest released major version and the current
`main` branch.
Security fixes are applied to the latest 2.x release and the current `main`
branch.

| Version | Supported |
| Version or ref | Supported |
| --- | --- |
| 2.x | Yes |
| 1.x | No |
| 0.x | No |
| `main` | Yes |
| 1.x and earlier | No |

## Report a Vulnerability

Expand All @@ -23,12 +23,12 @@ Email [martin.calander@gmail.com](mailto:martin.calander@gmail.com) with:
- relevant operating system, Unity, Git, and GitHub CLI versions;
- suggested remediation, if available.

Do not include real credentials or third-party private repository data. Encrypt
sensitive attachments before sending and request a secure exchange method when
needed.
Do not include real credentials or third-party private repository data. Do not
email sensitive attachments; ask for a secure exchange method first.

You can expect acknowledgment within 72 hours and an initial assessment within
seven days. Disclosure timing will be coordinated around a fix and release.
I aim to acknowledge reports within 72 hours and provide an initial assessment
within seven days. Disclosure timing will be coordinated around a fix and
release.

## Security Model

Expand All @@ -40,7 +40,8 @@ The package launches `git` and optional `gh` processes with
- repository URLs, branch names, package names, and managed paths are validated;
- network repositories are limited to HTTPS and SSH; plaintext `http://`,
`git://`, embedded credentials, and executable remote helpers are rejected;
- mutations are restricted to direct `Packages/com.author.package` paths;
- submodule filesystem changes are restricted to validated direct
`Packages/<reverse-domain-name>` children;
- stdout and stderr are redirected, drained concurrently, bounded, and treated
as unusable for structural parsing when incomplete;
- commands have bounded timeouts;
Expand All @@ -58,17 +59,20 @@ credential manager, SSH agent, and GitHub CLI.
### Network access

- Git performs clone, fetch, remote branch, and submodule operations.
- GitHub CLI performs authenticated repository discovery and root
`package.json` checks.
- GitHub CLI performs authenticated repository discovery and retrieves root
package metadata. Catalogue entries require a valid root `package.json` and
matching `package.json.meta` from the same commit.
- The package does not contain its own HTTP client or telemetry.

### Filesystem access

The package reads project `.gitmodules` and package metadata. Mutating package
operations are constrained to validated direct children of `Packages/`.
The package reads project `.gitmodules` and package metadata. Submodule
filesystem changes are constrained to validated direct children of `Packages/`.
Persisted submodule URLs, local Git configuration, worktree origins, and
postconditions are revalidated around mutations. Root manifests must be bounded
regular UTF-8 files rather than symbolic links or reparse points.
postconditions are revalidated around mutations. Catalogue entries and
read-only installs require bounded, strict-UTF-8 root `package.json` and
`package.json.meta` blobs from the same commit. Local package metadata must be
regular files rather than symbolic links or reparse points.

## User Responsibilities

Expand Down
Loading