fix(pr): exempt file-licensed packages, accept the security type, and keep the DCO check robust (#4)
Found while bringing gclo into conformance (KofTwentyTwo/gclo#62). ## What - `pr.yml`: new `allow-dependencies-licenses` input (package URLs) passed to `actions/dependency-review-action`, for packages whose nuspec declares a license *file* (the dependency graph reports `NOASSERTION` / `LicenseRef-scancode-unknown`). gclo's `LibGit2Sharp`, `Microsoft.WindowsAppSDK` and `Microsoft.Windows.SDK.BuildTools` fail `pr / dependency-review` on every change otherwise (see gclo#70). - `pr.yml`: the title check accepts `security`, which `policies/sdlc.md` lists as an allowed type; `sdlc.md` gains `style`, which the check already accepted. - `pr.yml`: DCO check bug: for a commit whose author email is not linked to a GitHub account, `.author.login` is null and the TSV field is empty; bash's tab `IFS` collapses adjacent tabs, the columns shift, and the check reports "no Signed-off-by" for a commit that has one. The login is written as `-` now. - `exceptions/register.md`: EX-0003 (gclo's libgit2 GPL-2.0-with-linking-exception and Windows SDK license terms, K22-DEP-02) and EX-0004 (gclo's in-repository release workflow until the shared reusable release workflow exists, K22-CI-30 / K22-REL-04); EX-0002's "current state" now says gclo ships `SHA256SUMS` and attestations since v1.0.1-beta.1. - `configs/shell/PSScriptAnalyzerSettings.psd1`: `CheckOperator` and `PSAlignAssignmentStatement` contradict each other on every aligned multi-line hashtable (including this settings file); alignment is the Kingsrook rule, so `CheckOperator` is off. - `MAINTAINERS.md`: gclo's adoption status. ## How it was tested - `actionlint` clean; YAML parses. - The DCO failure mode and the license failure were both observed on gclo pull requests today (gclo#68 before the author email was fixed; gclo#70). - PSScriptAnalyzer 1.25.0 with the changed settings: gclo's four scripts report 0 findings; with the original settings the aligned hashtables in the settings file itself are flagged. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: James Maes <james@kof22.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit was merged in pull request #4.
This commit is contained in:
1 parent
855cf44091
commit
ae174f5495
13 files changed
+106
-27
No files matched your search
@@ -67,10 +67,14 @@ jobs:
|
||||
run: |
|
||||
set -euo pipefail
|
||||
archive="lychee-x86_64-unknown-linux-gnu.tar.gz"
|
||||
curl -fsSLO "https://github.com/lycheeverse/lychee/releases/download/lychee-v${LYCHEE_VERSION}/${archive}"
|
||||
echo "${LYCHEE_SHA256} ${archive}" | sha256sum --check --strict
|
||||
tar -xzf "${archive}"
|
||||
./lychee --offline --include-fragments --no-progress './**/*.md'
|
||||
tool="${RUNNER_TEMP}/lychee"
|
||||
mkdir -p "${tool}"
|
||||
curl -fsSL -o "${tool}/${archive}" "https://github.com/lycheeverse/lychee/releases/download/lychee-v${LYCHEE_VERSION}/${archive}"
|
||||
(cd "${tool}" && echo "${LYCHEE_SHA256} ${archive}" | sha256sum --check --strict)
|
||||
# The archive unpacks into a versioned directory with its own README and
|
||||
# docs; it is extracted outside the checkout so they are not link-checked.
|
||||
tar -xzf "${tool}/${archive}" -C "${tool}"
|
||||
"${tool}/lychee-x86_64-unknown-linux-gnu/lychee" --offline --include-fragments --no-progress './**/*.md'
|
||||
|
||||
conformance:
|
||||
name: conformance
|
||||
|
||||
@@ -30,6 +30,14 @@ on:
|
||||
description: Lowest advisory severity that fails dependency review (low, moderate, high, critical).
|
||||
type: string
|
||||
default: low
|
||||
allow-dependencies-licenses:
|
||||
description: >-
|
||||
Comma-separated package URLs (e.g. pkg:nuget/LibGit2Sharp) whose license the
|
||||
dependency graph cannot read because the package declares a license FILE
|
||||
instead of an SPDX expression. They are exempt from the license check only;
|
||||
each one needs an entry in exceptions/register.md.
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
permissions: {}
|
||||
|
||||
@@ -47,13 +55,13 @@ jobs:
|
||||
run: |
|
||||
# The title becomes the squash commit subject on main (K22-REPO-22), so it
|
||||
# must be a valid Conventional Commits 1.0 header of at most 100 characters.
|
||||
pattern='^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\([A-Za-z0-9][A-Za-z0-9._/-]*\))?!?: [^[:space:]].*[^.[:space:]]$'
|
||||
pattern='^(build|chore|ci|docs|feat|fix|perf|refactor|revert|security|style|test)(\([A-Za-z0-9][A-Za-z0-9._/-]*\))?!?: [^[:space:]].*[^.[:space:]]$'
|
||||
if [[ ${#PR_TITLE} -gt 100 ]]; then
|
||||
echo "::error title=PR title too long::${#PR_TITLE} characters; the limit is 100."
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! "$PR_TITLE" =~ $pattern ]]; then
|
||||
echo "::error title=PR title is not a Conventional Commit::Expected '<type>(<scope>)!: <description>' with type one of build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test, and no trailing period."
|
||||
echo "::error title=PR title is not a Conventional Commit::Expected '<type>(<scope>)!: <description>' with type one of build, chore, ci, docs, feat, fix, perf, refactor, revert, security, style, test, and no trailing period."
|
||||
printf 'Title was: %s\n' "$PR_TITLE"
|
||||
exit 1
|
||||
fi
|
||||
@@ -77,7 +85,9 @@ jobs:
|
||||
# Developer Certificate of Origin (https://developercertificate.org/):
|
||||
# each commit needs "Signed-off-by: Name <email>" whose email matches the
|
||||
# commit author (git commit -s). Bot accounts (login ending in [bot]) are
|
||||
# exempt; Dependabot signs off anyway.
|
||||
# exempt; Dependabot signs off anyway. An author with no GitHub login (an
|
||||
# email the account does not list) is written as "-": `read` with a tab
|
||||
# IFS collapses adjacent tabs, so an empty field would shift the columns.
|
||||
set -euo pipefail
|
||||
failed=0
|
||||
while IFS=$'\t' read -r sha email login message_b64; do
|
||||
@@ -94,7 +104,7 @@ jobs:
|
||||
failed=1
|
||||
fi
|
||||
done < <(gh api --paginate "repos/$REPO/pulls/$PR_NUMBER/commits" \
|
||||
--jq '.[] | [.sha, .commit.author.email, (.author.login // ""), (.commit.message | @base64)] | @tsv')
|
||||
--jq '.[] | [.sha, .commit.author.email, (.author.login // "-"), (.commit.message | @base64)] | @tsv')
|
||||
exit "$failed"
|
||||
|
||||
dependency-review:
|
||||
@@ -113,6 +123,7 @@ jobs:
|
||||
# malicious or vulnerable one is just as dangerous as a runtime one.
|
||||
fail-on-scopes: runtime, development, unknown
|
||||
allow-licenses: ${{ inputs.allow-licenses }}
|
||||
allow-dependencies-licenses: ${{ inputs.allow-dependencies-licenses }}
|
||||
license-check: true
|
||||
vulnerability-check: true
|
||||
comment-summary-in-pr: never
|
||||
@@ -0,0 +1,12 @@
|
||||
# markdownlint-cli2 configuration for the standards repository.
|
||||
#
|
||||
# K22-CODE-08 sets no line-length limit for prose, and the templates use
|
||||
# <details> blocks and emphasised sub-headings deliberately.
|
||||
config:
|
||||
default: true
|
||||
MD013: false # line length: wrapped prose is a style choice, not a rule
|
||||
MD033: false # inline HTML: release-checklist uses <details>/<summary>
|
||||
MD036: false # emphasis as heading: the exceptions register's summary lines
|
||||
MD041: false # first-line heading: PULL_REQUEST_TEMPLATE starts at ##
|
||||
ignores:
|
||||
- node_modules
|
||||
+1
-8
@@ -7,7 +7,6 @@ We pledge to make our community welcoming, safe, and equitable for all.
|
||||
|
||||
We are committed to fostering an environment that respects and promotes the dignity, rights, and contributions of all individuals, regardless of characteristics including race, ethnicity, caste, color, age, physical characteristics, neurodiversity, disability, sex or gender, gender identity or expression, sexual orientation, language, philosophy or religion, national or social origin, socio-economic position, level of education, or other status. The same privileges of participation are extended to everyone who participates in good faith and in accordance with this Covenant.
|
||||
|
||||
|
||||
## Encouraged Behaviors
|
||||
|
||||
While acknowledging differences in social norms, we all strive to meet our community's expectations for positive behavior. We also understand that our words and actions may be interpreted differently than we intend based on culture, background, or native language.
|
||||
@@ -22,7 +21,6 @@ With these considerations in mind, we agree to behave mindfully toward each othe
|
||||
6. Committing to **repairing harm** when it occurs.
|
||||
7. Behaving in other ways that promote and sustain the **well-being of our community**.
|
||||
|
||||
|
||||
## Restricted Behaviors
|
||||
|
||||
We agree to restrict the following behaviors in our community. Instances, threats, and promotion of these behaviors are violations of this Code of Conduct.
|
||||
@@ -42,16 +40,14 @@ We agree to restrict the following behaviors in our community. Instances, threat
|
||||
3. **Promotional materials**. Sharing marketing or other commercial content in a way that is outside the norms of the community.
|
||||
4. **Irresponsible communication.** Failing to responsibly present content which includes, links or describes any other restricted behaviors.
|
||||
|
||||
|
||||
## Reporting an Issue
|
||||
|
||||
Tensions can occur between community members even when they are trying their best to collaborate. Not every conflict represents a code of conduct violation, and this Code of Conduct reinforces encouraged behaviors and norms that can help avoid conflicts and minimize harm.
|
||||
|
||||
When an incident does occur, it is important to report it promptly. To report a possible violation, email the maintainer at james@kof22.com, or use the private "Report content" options GitHub provides. Reports are handled by the maintainer listed in [MAINTAINERS.md](MAINTAINERS.md).
|
||||
When an incident does occur, it is important to report it promptly. To report a possible violation, email the maintainer at <james@kof22.com>, or use the private "Report content" options GitHub provides. Reports are handled by the maintainer listed in [MAINTAINERS.md](MAINTAINERS.md).
|
||||
|
||||
Community Moderators take reports of violations seriously and will make every effort to respond in a timely manner. They will investigate all reports of code of conduct violations, reviewing messages, logs, and recordings, or interviewing witnesses and other participants. Community Moderators will keep investigation and enforcement actions as transparent as possible while prioritizing safety and confidentiality. In order to honor these values, enforcement actions are carried out in private with the involved parties, but communicating to the whole community may be part of a mutually agreed upon resolution.
|
||||
|
||||
|
||||
## Addressing and Repairing Harm
|
||||
|
||||
If an investigation by the Community Moderators finds that this Code of Conduct has been violated, the following enforcement ladder may be used to determine how best to repair harm, based on the incident's impact on the individuals involved and the community as a whole. Depending on the severity of a violation, lower rungs on the ladder may be skipped.
|
||||
@@ -75,12 +71,10 @@ If an investigation by the Community Moderators finds that this Code of Conduct
|
||||
|
||||
This enforcement ladder is intended as a guideline. It does not limit the ability of Community Managers to use their discretion and judgment, in keeping with the best interests of our community.
|
||||
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public or other spaces. Examples of representing our community include using an official email address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
|
||||
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the Contributor Covenant, version 3.0, permanently available at [https://www.contributor-covenant.org/version/3/0/](https://www.contributor-covenant.org/version/3/0/).
|
||||
@@ -88,4 +82,3 @@ This Code of Conduct is adapted from the Contributor Covenant, version 3.0, perm
|
||||
Contributor Covenant is stewarded by the Organization for Ethical Source and licensed under CC BY-SA 4.0. To view a copy of this license, visit [https://creativecommons.org/licenses/by-sa/4.0/](https://creativecommons.org/licenses/by-sa/4.0/)
|
||||
|
||||
For answers to common questions about Contributor Covenant, see the FAQ at [https://www.contributor-covenant.org/faq](https://www.contributor-covenant.org/faq). Translations are provided at [https://www.contributor-covenant.org/translations](https://www.contributor-covenant.org/translations). Additional enforcement and community guideline resources can be found at [https://www.contributor-covenant.org/resources](https://www.contributor-covenant.org/resources). The enforcement ladder was inspired by the work of [Mozilla’s code of conduct team](https://github.com/mozilla/inclusion).
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ conformance version in its README once it passes the conformance checker.
|
||||
| --- | --- | --- | --- |
|
||||
| [standards](https://github.com/KofTwentyTwo/standards) | These policies, standards, configs, and reusable workflows | Product | Not yet: rulesets and CI being added |
|
||||
| [AppKit](https://github.com/KofTwentyTwo/AppKit) | Shared foundation packages for Windows desktop apps | Product | Adoption in progress |
|
||||
| [gclo](https://github.com/KofTwentyTwo/gclo) | Clone and update every repository of a GitHub organization (Windows app and CLI) | Product | Adoption in progress |
|
||||
| [gclo](https://github.com/KofTwentyTwo/gclo) | Clone and update every repository of a GitHub organization (Windows app and CLI) | Product | Adoption in progress: standards gates, governance files, and the Kingsrook layout are in review (gclo #62); settings and exceptions pending |
|
||||
|
||||
### Awaiting classification
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ Windows services are covered in [Variants](#variants).
|
||||
|
||||
## 2. Solution layout
|
||||
|
||||
```
|
||||
```text
|
||||
<App>.slnx
|
||||
Directory.Build.props quality gate, version prefix, package metadata
|
||||
Directory.Packages.props every package version (central package management)
|
||||
|
||||
@@ -8,9 +8,9 @@ Standards: [Java profile](../../standards/coding/java.md),
|
||||
| File | What it is | Origin |
|
||||
| --- | --- | --- |
|
||||
| [`Kingsrook_Code_Style.xml`](Kingsrook_Code_Style.xml) | IDE code-style scheme: Java, JavaScript, TypeScript, JSON, XML, SQL, Shell, CSS, HTML, Groovy, VTL | Kingsrook (Apache-2.0), unmodified |
|
||||
| [`project/.idea/codeStyles/`](project/.idea/codeStyles) | The same scheme as a per-project style, committed so the whole team gets it automatically | Derived from the above |
|
||||
| [`project/.idea/checkstyle-idea.xml`](project/.idea/checkstyle-idea.xml) | CheckStyle-IDEA plugin settings pointing at the published KofTwentyTwo checkstyle config | KofTwentyTwo |
|
||||
| [`project/.idea/copyright/`](project/.idea/copyright) + [`KofTwentyTwo_Copyright_Profile.xml`](KofTwentyTwo_Copyright_Profile.xml) | Copyright profile that inserts the KofTwentyTwo SPDX header (K22-CODE-24) | KofTwentyTwo |
|
||||
| `project/.idea/codeStyles/` (not yet published) | The same scheme as a per-project style, committed so the whole team gets it automatically | Derived from the above |
|
||||
| `project/.idea/checkstyle-idea.xml` (not yet published) | CheckStyle-IDEA plugin settings pointing at the published KofTwentyTwo checkstyle config | KofTwentyTwo |
|
||||
| `project/.idea/copyright/` (not yet published) + [`KofTwentyTwo_Copyright_Profile.xml`](KofTwentyTwo_Copyright_Profile.xml) | Copyright profile that inserts the KofTwentyTwo SPDX header (K22-CODE-24) | KofTwentyTwo |
|
||||
| [`Kingsrook_Copyright_Profile.xml`](Kingsrook_Copyright_Profile.xml) | QQQ's own Apache-2.0 header, for QQQ-derived code only | Kingsrook, unmodified |
|
||||
| [`live-templates/`](live-templates) | Kingsrook Java and SQL live templates (method, getter/setter/fluent setter, JUnit lifecycle, Liquibase changesets) | Kingsrook, unmodified |
|
||||
|
||||
|
||||
@@ -32,7 +32,9 @@
|
||||
# is not checked either way.
|
||||
CheckOpenParen = $false
|
||||
CheckOpenBrace = $false
|
||||
CheckOperator = $true
|
||||
# Kingsrook aligns the `=` of consecutive assignments (PSAlignAssignmentStatement
|
||||
# below); CheckOperator would then flag every aligned line, so it is off.
|
||||
CheckOperator = $false
|
||||
CheckPipe = $true
|
||||
CheckSeparator = $true
|
||||
CheckParameter = $true
|
||||
|
||||
+50
-2
@@ -7,6 +7,8 @@ Open and closed exceptions to the KofTwentyTwo standards. The process is in
|
||||
| --- | --- | --- | --- | --- |
|
||||
| [EX-0001](#ex-0001) | Open | K22-REPO-20 (approval count), OSPS-QA-07.01 | All repositories | When a second maintainer joins; reviewed 2027-10-09 |
|
||||
| [EX-0002](#ex-0002) | Open | K22-REL-05 (Authenticode signing of Windows binaries) | Windows desktop apps (gclo, AppKit samples, future apps) | When the Azure Trusted Signing identity is validated, at the latest 2027-04-09 |
|
||||
| [EX-0003](#ex-0003) | Open | K22-DEP-02 (license allowlist) | gclo | Reviewed yearly, next on 2027-10-09 |
|
||||
| [EX-0004](#ex-0004) | Open | K22-CI-30, K22-REL-04 (shared release workflow) | gclo | When the shared reusable release workflow ships, at the latest 2027-04-09 |
|
||||
|
||||
## EX-0001
|
||||
|
||||
@@ -50,8 +52,54 @@ Open and closed exceptions to the KofTwentyTwo standards. The process is in
|
||||
- **Compensating controls:** once the shared release workflow ships, every release asset
|
||||
is listed in `SHA256SUMS` and carries a GitHub build-provenance attestation
|
||||
(`K22-REL-04`), so integrity and origin can be verified with `gh attestation verify`
|
||||
even without a signature. **Current state:** gclo's existing releases have neither;
|
||||
they gain them when gclo moves to the shared release workflow.
|
||||
even without a signature. **Current state:** since v1.0.1-beta.1 every gclo release
|
||||
asset is listed in `SHA256SUMS` and attested (by gclo's own release workflow, see
|
||||
EX-0004); releases before that have neither.
|
||||
- **Expires:** when the signing identity is validated and the shared release workflow
|
||||
signs Windows binaries; at the latest 2027-04-09.
|
||||
- **Owner:** the maintainer.
|
||||
|
||||
## EX-0003
|
||||
|
||||
**gclo ships libgit2 (GPL-2.0 with linking exception) and the Microsoft Windows SDK packages**
|
||||
|
||||
- **Requirements:** `K22-DEP-02` requires shipped dependencies to carry an allowlisted
|
||||
license; any GPL variant needs a recorded exception.
|
||||
- **Scope:** `KofTwentyTwo/gclo`: the NuGet packages `LibGit2Sharp` (MIT, bundling the
|
||||
native `libgit2` under GPL-2.0 *with the linking exception*, which permits linking
|
||||
from MIT code without GPL obligations), `Microsoft.WindowsAppSDK` (Microsoft
|
||||
Software License Terms, redistributable runtime), and
|
||||
`Microsoft.Windows.SDK.BuildTools` (Windows SDK license, build-time only). All three
|
||||
declare their license as a file, so GitHub's dependency graph reports them as
|
||||
`NOASSERTION`/`unknown` and the `pr / dependency-review` license check fails on any
|
||||
change to them.
|
||||
- **Reason:** there is no alternative git implementation for .NET with libgit2's
|
||||
maturity, and a WinUI 3 app cannot exist without the Windows App SDK.
|
||||
- **Risk:** none to users under the linking exception and Microsoft's redistribution
|
||||
terms; the risk is procedural (the automated license gate cannot evaluate them).
|
||||
- **Compensating controls:** the three packages are named explicitly in the
|
||||
`allow-dependencies-licenses` input of `pr.yml`, so every other package still goes
|
||||
through the allowlist; vulnerability checks still apply to them; their terms are
|
||||
linked from gclo's README attributions.
|
||||
- **Expires:** reviewed yearly, next on 2027-10-09.
|
||||
- **Owner:** the maintainer.
|
||||
|
||||
## EX-0004
|
||||
|
||||
**gclo releases are built by an in-repository workflow until the shared release workflow exists**
|
||||
|
||||
- **Requirements:** `K22-CI-30` and `K22-REL-04` require releases to be built and
|
||||
attested by a reusable release workflow from this repository (SLSA Build L3).
|
||||
- **Scope:** `KofTwentyTwo/gclo` (`.github/workflows/release.yml`).
|
||||
- **Reason:** this repository does not yet publish a reusable release workflow; the
|
||||
requirement cannot be met by any caller until it does.
|
||||
- **Risk:** the provenance's `builder.id` names gclo's own workflow rather than an
|
||||
isolated one, so a compromise of gclo's repository could alter the build definition
|
||||
and its attestation together (SLSA Build L2 rather than L3).
|
||||
- **Compensating controls:** the release job is gated on a protected `v*` tag that
|
||||
must be on `main`, re-runs the CI gates, uses SHA-pinned actions and no caches,
|
||||
attests provenance and SBOMs through GitHub's OIDC-based attestation actions, and
|
||||
publishes immutable releases with `SHA256SUMS`.
|
||||
- **Expires:** when the shared reusable release workflow ships and gclo calls it; at
|
||||
the latest 2027-04-09.
|
||||
- **Owner:** the maintainer.
|
||||
@@ -0,0 +1,9 @@
|
||||
# lychee configuration for the docs gate (ci.yml "Link check (internal links)").
|
||||
#
|
||||
# Templates link to files that exist in the repository that adopts them, not
|
||||
# here: the ADR template's "Superseded by" placeholder and the LICENSE every
|
||||
# repository ships at its root.
|
||||
exclude = [
|
||||
'NNNN-title\.md$',
|
||||
'templates/repo/LICENSE$',
|
||||
]
|
||||
+1
-1
@@ -45,7 +45,7 @@ bold capitals.
|
||||
Every requirement has a stable ID so it can be cited from code, CI output, PRs, and the
|
||||
compliance crosswalks:
|
||||
|
||||
```
|
||||
```text
|
||||
K22-<AREA>-<NN>
|
||||
```
|
||||
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ still-supported older line.
|
||||
[Conventional Commits 1.0](https://www.conventionalcommits.org/en/v1.0.0/):
|
||||
`<type>(<optional scope>): <description>`, with `!` or a `BREAKING CHANGE:` footer for
|
||||
incompatible changes. Allowed types: `feat`, `fix`, `perf`, `refactor`, `docs`, `test`,
|
||||
`build`, `ci`, `chore`, `revert`, `security`.
|
||||
`build`, `ci`, `chore`, `revert`, `style`, `security`.
|
||||
*Why:* versions and release notes are derived from history, so history must be
|
||||
machine-readable. *Verified by:* `pr / title` check; commit-msg hook.
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ IntelliJ plugin generates both comment forms.
|
||||
(Python, Rust, Swift); review for the rest.
|
||||
|
||||
**K22-CODE-10 (SHOULD)** Comments inside a type or method body are flower boxes: a line
|
||||
of `/`, the text between `// ` and ` //` padded so every line is the same length, and a
|
||||
of `/`, the text between `//` and `//` (one space inside each) padded so every line is the same length, and a
|
||||
closing line of `/`.
|
||||
|
||||
```java
|
||||
|
||||
Reference in new issue
Block a user