Splitting ref and sha into two fields correctly for the intake form (#1788)

* Splitting ref and sha into two fields correctly for the intake form

* Enforce 40-character commit SHA in validateImmutableRef

Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com>

* Add backward compatibility for legacy checklist text and field title

Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com>

* Avoid unnecessary array spread when iterating checklist equivalents

Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com>
This commit is contained in:
Aaron Powell
2026-05-22 10:54:34 +10:00
committed by GitHub
parent 2ca49df9d4
commit 6fc05f480e
5 changed files with 111 additions and 32 deletions
+27 -6
View File
@@ -11,7 +11,7 @@ export const EXTERNAL_PLUGIN_POLICIES = Object.freeze({
requireRepository: true,
requireKeywords: true,
requireLicense: false,
requireImmutableRef: false,
requireImmutableLocator: false,
}),
publicSubmission: Object.freeze({
allowedSourceTypes: ["github"],
@@ -19,7 +19,7 @@ export const EXTERNAL_PLUGIN_POLICIES = Object.freeze({
requireRepository: true,
requireKeywords: true,
requireLicense: true,
requireImmutableRef: true,
requireImmutableLocator: true,
}),
});
@@ -263,9 +263,24 @@ function validateImmutableRef(ref, prefix, errors) {
if (ref.startsWith("refs/") && !ref.startsWith("refs/tags/")) {
errors.push(`${prefix}: "source.ref" must be a tag ref or commit SHA`);
}
if (/^[0-9a-f]+$/i.test(ref) && ref.length !== 40) {
errors.push(`${prefix}: "source.ref" must be a full 40-character commit SHA when referencing a commit`);
}
}
function validateGitHubSource(source, prefix, errors, requireImmutableRef) {
function validateCommitSha(sha, prefix, errors) {
if (!isNonEmptyString(sha)) {
errors.push(`${prefix}: "source.sha" must be a non-empty string when provided`);
return;
}
if (!/^[0-9a-f]{40}$/i.test(sha)) {
errors.push(`${prefix}: "source.sha" must be a full 40-character commit SHA`);
}
}
function validateGitHubSource(source, prefix, errors, requireImmutableLocator) {
if (!source || typeof source !== "object" || Array.isArray(source)) {
errors.push(`${prefix}: "source" must be an object`);
return;
@@ -287,8 +302,14 @@ function validateGitHubSource(source, prefix, errors, requireImmutableRef) {
if (source.ref !== undefined) {
validateImmutableRef(source.ref, prefix, errors);
} else if (requireImmutableRef) {
errors.push(`${prefix}: "source.ref" is required for public external plugin submissions`);
}
if (source.sha !== undefined) {
validateCommitSha(source.sha, prefix, errors);
}
if (requireImmutableLocator && source.ref === undefined && source.sha === undefined) {
errors.push(`${prefix}: one of "source.ref" or "source.sha" is required for public external plugin submissions`);
}
}
@@ -325,7 +346,7 @@ export function validateExternalPlugin(plugin, index, options = {}) {
} else if (!policy.allowedSourceTypes.includes(plugin.source.source)) {
errors.push(`${prefix}: "source.source" must be one of: ${policy.allowedSourceTypes.join(", ")}`);
} else if (plugin.source.source === "github") {
validateGitHubSource(plugin.source, prefix, errors, policy.requireImmutableRef);
validateGitHubSource(plugin.source, prefix, errors, policy.requireImmutableLocator);
}
return { errors, warnings };