From b275e41028709102a2968c6f4abeb9c4507ea877 Mon Sep 17 00:00:00 2001 From: tstollin Date: Tue, 21 Jul 2026 14:06:52 +0200 Subject: [PATCH] feat: include json schemas for validation --- .github/pull_request_template.md | 2 +- .github/workflows/ci.yml | 7 +- .github/workflows/release.yml | 1 - .gitignore | 1 - AGENTS.md | 5 +- CONTRIBUTING.md | 13 +- Makefile | 33 + schemas/autolinkspreset_v1alpha1.json | 126 +++ .../codesecurityconfiguration_v1alpha1.json | 369 +++++++++ schemas/organization_v1alpha1.json | 419 ++++++++++ schemas/repository_v1alpha1.json | 448 ++++++++++ schemas/rulesetpreset_v1alpha1.json | 766 ++++++++++++++++++ schemas/team_v1alpha1.json | 199 +++++ schemas/webhookignorepreset_v1alpha1.json | 98 +++ schemas/webhookpreset_v1alpha1.json | 224 +++++ 15 files changed, 2695 insertions(+), 16 deletions(-) create mode 100644 schemas/autolinkspreset_v1alpha1.json create mode 100644 schemas/codesecurityconfiguration_v1alpha1.json create mode 100644 schemas/organization_v1alpha1.json create mode 100644 schemas/repository_v1alpha1.json create mode 100644 schemas/rulesetpreset_v1alpha1.json create mode 100644 schemas/team_v1alpha1.json create mode 100644 schemas/webhookignorepreset_v1alpha1.json create mode 100644 schemas/webhookpreset_v1alpha1.json diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 08a003d..29b218a 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -15,7 +15,7 @@ - [ ] My commits follow the [Conventional Commits](https://www.conventionalcommits.org/) format - [ ] I have added/updated unit tests for any new or changed templates - [ ] I have updated documentation (README, CONTRIBUTING, values comments) if needed -- [ ] I have updated the generated CRDs and Manifest +- [ ] I have updated the generated files using `make codegen` ## Related Issues diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5b5bd04..a3ffe3e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,15 +60,12 @@ jobs: go-version-file: go.mod - name: Run code generation - run: | - make manifests - make generate - make crd-docs + run: make codegen - name: Check for uncommitted changes run: | if [ -n "$(git status --porcelain)" ]; then - echo "::error::Generated code is out of date. Please run 'make manifests generate crd-docs' and commit the changes." + echo "::error::Generated code is out of date. Please run 'make codegen' and commit the changes." echo "" echo "Changed files:" git status --short diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5bb7888..c9c0558 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -123,4 +123,3 @@ jobs: platforms: linux/amd64,linux/arm64 cache-from: type=gha cache-to: type=gha,mode=max - diff --git a/.gitignore b/.gitignore index 84d2ced..8e6c980 100644 --- a/.gitignore +++ b/.gitignore @@ -46,7 +46,6 @@ go.work !vendor/**/zz_generated.* # editor and IDE paraphernalia -.vscode *.swp *.swo *~ diff --git a/AGENTS.md b/AGENTS.md index 5135dee..9358bb9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -60,8 +60,7 @@ Ensure you run them against a dedicated [Kind](https://kind.sigs.k8s.io/) cluste **After editing `*_types.go` or markers:** ``` -make manifests # Regenerate CRDs/RBAC from markers -make generate # Regenerate DeepCopy methods +make codegen # Regenerate CRDs/RBAC, DeepCopy, docs, and validation schemas ``` **After editing `*.go` files:** @@ -154,7 +153,7 @@ Tests use **Ginkgo + Gomega** (BDD style). Check `suite_test.go` for setup. ```bash # 1. Regenerate manifests -make manifests generate +make codegen # 2. Build & deploy export IMG=/:tag diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f3b7e5a..c7ab8e8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -86,6 +86,7 @@ Run `make help` for the full list. The most important targets are: | `make lint-fix` | Lint with auto-fix | | `make generate` | Regenerate deepcopy and apply-configuration code | | `make manifests` | Regenerate CRDs and RBAC from kubebuilder markers | +| `make codegen` | Run all code generation steps after an API change (manifests, generate, crd-docs, schemas) | | `make install` | Install CRDs into the current cluster | | `make deploy IMG=` | Deploy the operator to the current cluster | | `make undeploy` | Remove the operator from the current cluster | @@ -93,10 +94,10 @@ Run `make help` for the full list. The most important targets are: ### After Editing `*_types.go` or Kubebuilder Markers -Always regenerate manifests and code: +Always regenerate all derived artifacts: ```bash -make manifests generate +make codegen ``` ### After Any Go Code Change @@ -152,6 +153,8 @@ kubebuilder create webhook --group github --version v1alpha1 --kind --def | `config/crd/bases/*.yaml` | `make manifests` | | `config/rbac/role.yaml` | `make manifests` | | `config/webhook/manifests.yaml` | `make manifests` | +| `docs/crds.md` | `make crd-docs` | +| `schemas/*.json` | `make schemas` | | `PROJECT` | Kubebuilder CLI | ### Where to Look @@ -265,7 +268,7 @@ Edit `.env` freely — it won't be committed. The template (`.env.tmpl`) contain 2. Make your changes, following the conventions above. 3. Run the full validation suite: ```bash - make manifests generate # if you changed types or markers + make codegen # if you changed types or markers make lint-fix make test ``` @@ -277,10 +280,10 @@ Edit `.env` freely — it won't be committed. The template (`.env.tmpl`) contain ### Codegen Check -The **Codegen Check** workflow verifies that generated code is up to date on every PR. It runs `make manifests`, `make generate`, and `make crd-docs`, then fails if there are uncommitted changes. Always run these before pushing: +The **Codegen Check** workflow verifies that generated code is up to date on every PR. It runs all generation steps, then fails if there are uncommitted changes. Always run this before pushing: ```bash -make manifests generate crd-docs +make codegen ``` ### Helm Chart Update diff --git a/Makefile b/Makefile index 3a4c442..427db86 100644 --- a/Makefile +++ b/Makefile @@ -231,6 +231,7 @@ GINKGO ?= $(LOCALBIN)/ginkgo ## Tool Versions KUSTOMIZE_VERSION ?= v5.8.1 CONTROLLER_TOOLS_VERSION ?= v0.21.0 +KUBECONFORM_VERSION ?= v0.8.0 #ENVTEST_VERSION is the controller-runtime version to use for setup-envtest, derived from go.mod ENVTEST_VERSION ?= $(shell v='$(call gomodver,sigs.k8s.io/controller-runtime)'; \ @@ -244,6 +245,7 @@ ENVTEST_K8S_VERSION ?= $(shell v='$(call gomodver,k8s.io/api)'; \ GOLANGCI_LINT_VERSION ?= v2.12.2 GINKGO_VERSION ?= v2.27.2 # Match the version in go.mod +OPENAPI2JSONSCHEMA ?= $(LOCALBIN)/openapi2jsonschema .PHONY: kustomize kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. @@ -303,6 +305,19 @@ $(CRD_REF_DOCS): $(LOCALBIN) crd-docs: crd-ref-docs generate $(CRD_REF_DOCS) --source-path ./api/v1alpha1 --config ./crd-ref-docs.config.yaml --output-path=./docs/crds.md --renderer=markdown +.PHONY: codegen +codegen: manifests generate crd-docs schemas ## Regenerate all derived artifacts after an API change (CRDs, deepcopy, docs, schemas). + +.PHONY: openapi2jsonschema-tool +openapi2jsonschema-tool: $(OPENAPI2JSONSCHEMA) ## Download and build openapi2jsonschema from kubeconform if necessary. +$(OPENAPI2JSONSCHEMA): $(LOCALBIN) + $(call clone-and-build-tool,$(OPENAPI2JSONSCHEMA),yannh/kubeconform,$(KUBECONFORM_VERSION),openapi2jsonschema-go) + +.PHONY: schemas +schemas: manifests openapi2jsonschema-tool ## Generate per-kind JSON Schema files for CR validation into schemas/. + @mkdir -p schemas + @cd schemas && for crd in ../config/crd/bases/*.yaml; do "$(OPENAPI2JSONSCHEMA)" "$$crd"; done + # Add the Grafana plugin .PHONY: grafana @@ -326,6 +341,24 @@ mv "$(LOCALBIN)/$$(basename "$(1)")" "$(1)-$(3)" ;\ ln -sf "$$(basename "$(1)-$(3)")" "$(1)" endef +# clone-and-build-tool clones a GitHub repo at a given tag and builds a Go binary from a subdirectory. +# $1 - target binary path (without version suffix) +# $2 - GitHub repo slug (e.g. yannh/kubeconform) +# $3 - version tag to clone +# $4 - subdirectory that contains the go.mod and main package +define clone-and-build-tool +@[ -f "$(1)-$(3)" ] || { \ +set -e; \ +echo "Building $$(basename "$(1)") from github.com/$(2) $(3)..."; \ +tmpdir=$$(mktemp -d); \ +git clone --quiet --depth=1 --branch "$(3)" "https://github.com/$(2).git" "$$tmpdir"; \ +( cd "$$tmpdir/$(4)" && go build -o "$(1)-$(3)" . ); \ +rm -rf "$$tmpdir"; \ +}; \ +[ -L "$(1)" ] && [ -e "$(1)" ] || \ +ln -sf "$$(basename "$(1)-$(3)")" "$(1)" +endef + define gomodver $(shell go list -m -f '{{if .Replace}}{{.Replace.Version}}{{else}}{{.Version}}{{end}}' $(1) 2>/dev/null) endef diff --git a/schemas/autolinkspreset_v1alpha1.json b/schemas/autolinkspreset_v1alpha1.json new file mode 100644 index 0000000..46dd36d --- /dev/null +++ b/schemas/autolinkspreset_v1alpha1.json @@ -0,0 +1,126 @@ +{ + "description": "AutolinksPreset is the Schema for the autolinkspresets API", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "description": "spec defines the desired state of AutolinksPreset", + "properties": { + "autolinks": { + "description": "AutolinkList is a list of autolink configurations to create in repositories.\nEach autolink defines a prefix that triggers link generation and a URL template.", + "items": { + "description": "Autolink defines an automatic link reference for external resources.\nWhen a reference matching KeyPrefix is found in issues, pull requests, or commit messages,\nGitHub automatically converts it to a clickable link using the URLTemplate.\nSee: https://docs.github.com/en/rest/repos/autolinks", + "properties": { + "isAlphanumeric": { + "default": false, + "description": "IsAlphanumeric determines whether the reference must be alphanumeric.\n- true: the parameter of the url_template matches alphanumeric characters `A-Z` (case insensitive), `0-9`, and `-`\n- false: reference only matches numeric characters.", + "type": "boolean" + }, + "keyPrefix": { + "description": "KeyPrefix is the text prefix that triggers autolink creation.\nWhen text starts with this prefix followed by a reference, it becomes a link.\nExamples: \"JIRA-\", \"TICKET-\", \"BUG-\"", + "maxLength": 20, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9-]{0,19}$", + "type": "string" + }, + "urlTemplate": { + "description": "URLTemplate is the URL pattern used to generate links.\nUse as a placeholder for the reference number/ID.\nExample: \"https://jira.example.com/browse/\" converts \"JIRA-123\" to \"https://jira.example.com/browse/123\"", + "maxLength": 200, + "type": "string" + } + }, + "required": [ + "isAlphanumeric", + "keyPrefix", + "urlTemplate" + ], + "type": "object", + "additionalProperties": false + }, + "type": "array" + } + }, + "type": "object", + "additionalProperties": false + }, + "status": { + "description": "status defines the observed state of AutolinksPreset", + "properties": { + "conditions": { + "description": "conditions represent the current state of the AutolinksPreset resource.\nEach condition has a unique type and reflects the status of a specific aspect of the resource.\n\nStandard condition types include:\n- \"Available\": the resource is fully functional\n- \"Progressing\": the resource is being created or updated\n- \"Degraded\": the resource failed to reach or maintain its desired state\n\nThe status of each condition is one of True, False, or Unknown.", + "items": { + "description": "Condition contains details for one aspect of the current state of this API Resource.", + "properties": { + "lastTransitionTime": { + "description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.", + "format": "date-time", + "type": "string" + }, + "message": { + "description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.", + "maxLength": 32768, + "type": "string" + }, + "observedGeneration": { + "description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.", + "format": "int64", + "minimum": 0, + "type": "integer" + }, + "reason": { + "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.", + "maxLength": 1024, + "minLength": 1, + "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$", + "type": "string" + }, + "status": { + "description": "status of the condition, one of True, False, Unknown.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + }, + "type": { + "description": "type of condition in CamelCase or in foo.example.com/CamelCase.", + "maxLength": 316, + "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$", + "type": "string" + } + }, + "required": [ + "lastTransitionTime", + "message", + "reason", + "status", + "type" + ], + "type": "object", + "additionalProperties": false + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map" + } + }, + "type": "object", + "additionalProperties": false + } + }, + "required": [ + "spec" + ], + "type": "object" +} diff --git a/schemas/codesecurityconfiguration_v1alpha1.json b/schemas/codesecurityconfiguration_v1alpha1.json new file mode 100644 index 0000000..c508de7 --- /dev/null +++ b/schemas/codesecurityconfiguration_v1alpha1.json @@ -0,0 +1,369 @@ +{ + "description": "CodeSecurityConfiguration is the Schema for the codesecurityconfigurations API", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "description": "spec defines the desired state of CodeSecurityConfiguration", + "properties": { + "advancedSecurity": { + "description": "AdvancedSecurity enables or disables GitHub Advanced Security features.\n- \"enabled\": Enable Advanced Security (required for code scanning, secret scanning, and dependency review)\n- \"disabled\": Disable Advanced Security\n- \"code_security\": Enable code security features only\n- \"secret_protection\": Enable secret protection features only\nWarning: code_security and secret_protection are deprecated values for this field.\nPrefer the individual code_security and secret_protection fields to set the status of these features.\nSee: https://docs.github.com/en/get-started/learning-about-github/about-github-advanced-security", + "enum": [ + "enabled", + "disabled", + "code_security", + "secret_protection" + ], + "type": "string" + }, + "codeScanningDefaultSetup": { + "description": "CodeScanningDefaultSetup enables or disables default code scanning setup.\nDefault setup automatically configures code scanning with recommended settings.\nSee: https://docs.github.com/en/code-security/code-scanning/enabling-code-scanning/configuring-default-setup-for-code-scanning", + "enum": [ + "enabled", + "disabled", + "not_set" + ], + "type": "string" + }, + "codeScanningDefaultSetupOptions": { + "description": "CodeScanningDefaultSetupOptions configures runner options for default code scanning setup.", + "properties": { + "runnerLabel": { + "description": "RunnerLabel specifies the label of self-hosted runners to use.\nThis field is required when RunnerType is \"labeled\" and ignored otherwise.", + "type": "string" + }, + "runnerType": { + "description": "RunnerType specifies which type of runners to use for code scanning.\n- \"standard\": Use GitHub-hosted standard runners\n- \"labeled\": Use self-hosted runners with specific labels (requires RunnerLabel)\n- \"not_set\": No runner type is configured", + "enum": [ + "standard", + "labeled", + "not_set" + ], + "type": "string" + } + }, + "required": [ + "runnerType" + ], + "type": "object", + "additionalProperties": false + }, + "codeScanningDelegatedAlertDismissal": { + "description": "CodeScanningDelegatedAlertDismissal enables users to dismiss code scanning alerts.\nWhen enabled, users with appropriate permissions can dismiss alerts that don't require action.", + "enum": [ + "enabled", + "disabled", + "not_set" + ], + "type": "string" + }, + "codeScanningOptions": { + "description": "CodeScanningOptions configures advanced code scanning options.", + "properties": { + "allowAdvanced": { + "description": "AllowAdvanced determines whether users can enable advanced code scanning features.\nWhen true, repository administrators can configure advanced code scanning settings beyond the default setup.", + "type": "boolean" + } + }, + "type": "object", + "additionalProperties": false + }, + "codeSecurity": { + "description": "CodeSecurity is a meta-setting that enables multiple code security features.", + "enum": [ + "enabled", + "disabled", + "not_set" + ], + "type": "string" + }, + "defaultForNewRepos": { + "description": "DefaultForNewRepos determines whether this configuration is automatically applied to new repositories.\n- \"all\": Apply to all new repositories\n- \"private_and_internal\": Apply only to new private and internal repositories\n- \"public\": Apply only to new public repositories", + "enum": [ + "all", + "private_and_internal", + "public" + ], + "type": "string" + }, + "dependabotAlerts": { + "description": "DependabotAlerts enables or disables Dependabot alerts for vulnerable dependencies.\nRequires DependencyGraph to be enabled.\nSee: https://docs.github.com/en/code-security/dependabot/dependabot-alerts/about-dependabot-alerts", + "enum": [ + "enabled", + "disabled", + "not_set" + ], + "type": "string" + }, + "dependabotSecurityUpdates": { + "description": "DependabotSecurityUpdates enables or disables Dependabot security updates.\nWhen enabled, Dependabot automatically creates pull requests to update vulnerable dependencies.\nRequires DependabotAlerts to be enabled.\nSee: https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/about-dependabot-security-updates", + "enum": [ + "enabled", + "disabled", + "not_set" + ], + "type": "string" + }, + "dependencyGraph": { + "description": "DependencyGraph enables or disables the dependency graph.\nThe dependency graph identifies all dependencies in your repository.\n- \"enabled\": Enable dependency graph\n- \"disabled\": Disable dependency graph\n- \"not_set\": Use default organization or repository setting\nSee: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-the-dependency-graph", + "enum": [ + "enabled", + "disabled", + "not_set" + ], + "type": "string" + }, + "dependencyGraphAutosubmitAction": { + "description": "DependencyGraphAutosubmitAction enables automatic submission of dependency information.\nWhen enabled, dependency information is automatically submitted from Actions workflows.", + "enum": [ + "enabled", + "disabled", + "not_set" + ], + "type": "string" + }, + "dependencyGraphAutosubmitActionOptions": { + "description": "DependencyGraphAutosubmitActionOptions configures options for automatic dependency submission.", + "properties": { + "labeledRunners": { + "description": "LabeledRunners indicates whether to use labeled runners for dependency submission actions.\nIf true, actions will run on runners with specific labels instead of GitHub-hosted runners.", + "type": "boolean" + } + }, + "type": "object", + "additionalProperties": false + }, + "description": { + "description": "Description provides additional information about the configuration's purpose and settings.", + "type": "string" + }, + "enforcement": { + "description": "Enforcement determines how strictly this configuration is applied.\n- \"enforced\": Configuration settings are strictly enforced and cannot be overridden\n- \"unenforced\": Configuration settings are recommended but can be overridden at the repository level", + "enum": [ + "enforced", + "unenforced" + ], + "type": "string" + }, + "name": { + "description": "Name is the display name of the code security configuration.", + "type": "string" + }, + "privateVulnerabilityReporting": { + "description": "PrivateVulnerabilityReporting enables or disables private vulnerability reporting.\nWhen enabled, security researchers can privately report vulnerabilities.\nSee: https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability", + "enum": [ + "enabled", + "disabled", + "not_set" + ], + "type": "string" + }, + "secretProtection": { + "description": "SecretProtection is a meta-setting that enables multiple secret protection features.", + "enum": [ + "enabled", + "disabled", + "not_set" + ], + "type": "string" + }, + "secretScanning": { + "description": "SecretScanning enables or disables secret scanning.\nSecret scanning detects secrets (like API keys and tokens) in your code.\nRequires AdvancedSecurity to be enabled.\nSee: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning", + "enum": [ + "enabled", + "disabled", + "not_set" + ], + "type": "string" + }, + "secretScanningDelegatedAlertDismissal": { + "description": "SecretScanningDelegatedAlertDismissal enables users to dismiss secret scanning alerts.\nWhen enabled, users with appropriate permissions can dismiss false-positive alerts.", + "enum": [ + "enabled", + "disabled", + "not_set" + ], + "type": "string" + }, + "secretScanningDelegatedBypass": { + "description": "SecretScanningDelegatedBypass enables delegated bypass for secret scanning push protection.\nWhen enabled, contributors can request bypass approval from designated reviewers.", + "enum": [ + "enabled", + "disabled", + "not_set" + ], + "type": "string" + }, + "secretScanningDelegatedBypassOptions": { + "description": "SecretScanningDelegatedBypassOptions configures reviewers who can approve bypass requests.", + "properties": { + "reviewers": { + "description": "Reviewers is a list of teams or organization roles that can review bypass requests.", + "items": { + "description": "BypassReviewer represents a team or role that can review secret scanning bypass requests.\nEither ReviewerId (for direct ID specification) or ReviewerName (for name-based resolution) must be set.\nSee: https://docs.github.com/en/rest/code-security/configurations", + "properties": { + "reviewerId": { + "description": "ReviewerId is the numeric ID of the reviewer (team ID or role ID).\nThis field is mutually exclusive with ReviewerName.", + "format": "int64", + "type": "integer" + }, + "reviewerName": { + "description": "ReviewerName is the name of the reviewer (team slug or role name) which will be resolved to an ID based on the ReviewerType.\nThis field is mutually exclusive with ReviewerId.\nFor TEAM type, this should be the team slug.\nFor ROLE type, this should be the role name.", + "type": "string" + }, + "reviewerType": { + "description": "ReviewerType specifies the type of reviewer.\n- \"TEAM\": A team within the organization (use team slug for ReviewerName)\n- \"ROLE\": An organization role (use role name for ReviewerName)", + "enum": [ + "TEAM", + "ROLE" + ], + "type": "string" + } + }, + "required": [ + "reviewerType" + ], + "type": "object", + "x-kubernetes-validations": [ + { + "message": "exactly one of the fields in [reviewerId reviewerName] must be set", + "rule": "[has(self.reviewerId),has(self.reviewerName)].filter(x,x==true).size() == 1" + } + ], + "additionalProperties": false + }, + "type": "array" + } + }, + "required": [ + "reviewers" + ], + "type": "object", + "additionalProperties": false + }, + "secretScanningGenericSecrets": { + "description": "SecretScanningGenericSecrets enables detection of generic secrets.\nThis uses AI to detect potential secrets that don't match specific patterns.", + "enum": [ + "enabled", + "disabled", + "not_set" + ], + "type": "string" + }, + "secretScanningNonProviderPatterns": { + "description": "SecretScanningNonProviderPatterns enables detection of non-provider secret patterns.\nThis expands secret scanning beyond known service provider patterns.", + "enum": [ + "enabled", + "disabled", + "not_set" + ], + "type": "string" + }, + "secretScanningPushProtection": { + "description": "SecretScanningPushProtection enables or disables push protection for secret scanning.\nWhen enabled, pushes containing detected secrets are blocked.\nRequires SecretScanning to be enabled.\nSee: https://docs.github.com/en/code-security/secret-scanning/push-protection-for-repositories-and-organizations", + "enum": [ + "enabled", + "disabled", + "not_set" + ], + "type": "string" + }, + "secretScanningValidityChecks": { + "description": "SecretScanningValidityChecks enables validation of detected secrets.\nWhen enabled, GitHub validates whether detected secrets are still active.", + "enum": [ + "enabled", + "disabled", + "not_set" + ], + "type": "string" + } + }, + "required": [ + "description", + "name" + ], + "type": "object", + "additionalProperties": false + }, + "status": { + "description": "status defines the observed state of CodeSecurityConfiguration", + "properties": { + "conditions": { + "description": "conditions represent the current state of the CodeSecurityConfiguration resource.\nEach condition has a unique type and reflects the status of a specific aspect of the resource.\n\nStandard condition types include:\n- \"Available\": the resource is fully functional\n- \"Progressing\": the resource is being created or updated\n- \"Degraded\": the resource failed to reach or maintain its desired state\n\nThe status of each condition is one of True, False, or Unknown.", + "items": { + "description": "Condition contains details for one aspect of the current state of this API Resource.", + "properties": { + "lastTransitionTime": { + "description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.", + "format": "date-time", + "type": "string" + }, + "message": { + "description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.", + "maxLength": 32768, + "type": "string" + }, + "observedGeneration": { + "description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.", + "format": "int64", + "minimum": 0, + "type": "integer" + }, + "reason": { + "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.", + "maxLength": 1024, + "minLength": 1, + "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$", + "type": "string" + }, + "status": { + "description": "status of the condition, one of True, False, Unknown.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + }, + "type": { + "description": "type of condition in CamelCase or in foo.example.com/CamelCase.", + "maxLength": 316, + "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$", + "type": "string" + } + }, + "required": [ + "lastTransitionTime", + "message", + "reason", + "status", + "type" + ], + "type": "object", + "additionalProperties": false + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map" + } + }, + "type": "object", + "additionalProperties": false + } + }, + "required": [ + "spec" + ], + "type": "object" +} diff --git a/schemas/organization_v1alpha1.json b/schemas/organization_v1alpha1.json new file mode 100644 index 0000000..c84df67 --- /dev/null +++ b/schemas/organization_v1alpha1.json @@ -0,0 +1,419 @@ +{ + "description": "Organization is the Schema for the organizations API", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "description": "spec defines the desired state of Organization", + "properties": { + "actionsSettings": { + "description": "ActionsSettings configures GitHub Actions permissions and behavior for the organization.\nThis includes which repositories can use Actions, which actions are allowed, and runner group configurations.\nSee: https://docs.github.com/en/rest/actions/permissions", + "properties": { + "allowedActions": { + "description": "AllowedActions configures which actions and workflows are allowed to run.\nMust be nil if EnabledRepositories is \"none\".\n- \"all\": All actions and reusable workflows are allowed\n- \"local_only\": Only actions and workflows defined in the same repository or organization are allowed\n- \"selected\": Only specific actions are allowed (requires SelectedAllowedActions)", + "enum": [ + "all", + "local_only", + "selected" + ], + "type": "string" + }, + "artifactAndLogRetentionDays": { + "default": 400, + "description": "ArtifactAndLogRetentionDays specifies how many days workflow artifacts and logs are retained.\nMust be between 1 and 400 days. Shorter retention periods reduce storage costs.", + "type": "integer" + }, + "canApprovePullRequestReviews": { + "default": false, + "description": "CanApprovePullRequestReviews determines whether the GITHUB_TOKEN can approve pull requests.\nWhen false, prevents workflows from approving pull requests automatically.", + "type": "boolean" + }, + "defaultWorkflowPermissions": { + "default": "read", + "description": "DefaultWorkflowPermissions sets the default GITHUB_TOKEN permissions for workflows.\n- \"read\": Token has read-only access to repository contents\n- \"write\": Token has read and write access to repository contents", + "enum": [ + "read", + "write" + ], + "type": "string" + }, + "enabledRepositories": { + "default": "none", + "description": "EnabledRepositories determines which repositories can use GitHub Actions.\n- \"all\": Actions enabled for all repositories\n- \"none\": Actions disabled for all repositories\n- \"selected\": Actions enabled for specific repositories (requires additional configuration)", + "enum": [ + "all", + "none", + "selected" + ], + "type": "string" + }, + "runnerGroups": { + "description": "RunnerGroups configures self-hosted runner groups for the organization.\nEach group can have different visibility and workflow restrictions.", + "items": { + "description": "RunnerGroup configures a self-hosted runner group for GitHub Actions in an organization.\nRunner groups allow you to control which repositories can use specific sets of self-hosted runners.\nSee: https://docs.github.com/en/rest/actions/self-hosted-runner-groups", + "properties": { + "name": { + "description": "Name is the unique name of the runner group within the organization.", + "type": "string" + }, + "restrictedToWorkflows": { + "default": false, + "description": "RestrictedToWorkflows determines whether this runner group can only run specific workflows.\nIf true, only workflows listed in SelectedWorkflows can use runners in this group.\nThis provides additional security by limiting which workflows can execute on sensitive runners.", + "type": "boolean" + }, + "selectedWorkflows": { + "description": "SelectedWorkflows lists the workflows that can use runners in this group.\nThis field is only used when RestrictedToWorkflows is true.\nEach entry must be a full workflow path with a reference (branch, tag, or SHA).\nExample: \"octo-org/octo-repo/.github/workflows/deploy.yaml@refs/heads/main\"", + "items": { + "type": "string" + }, + "type": "array" + }, + "visibility": { + "default": "all", + "description": "Visibility determines which repositories can access runners in this group.\n- \"all\": All repositories in the organization can use these runners\n- \"private\": Only private repositories can use these runners\n- \"selected\": Only specific repositories can use these runners (selected via AvailableActionsRunnerGroups in RepositorySpec)", + "enum": [ + "all", + "private", + "selected" + ], + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object", + "additionalProperties": false + }, + "type": "array" + }, + "selectedAllowedActions": { + "description": "SelectedAllowedActions specifies which actions are allowed when AllowedActions is \"selected\".\nThis field is required when AllowedActions is \"selected\" and ignored otherwise.", + "properties": { + "githubOwnedAllowed": { + "default": false, + "description": "GitHubOwnedAllowed determines whether actions created by GitHub are allowed to run.\nThis includes actions in the \"actions\" and \"github\" organizations.", + "type": "boolean" + }, + "patternsAllowed": { + "default": [], + "description": "PatternsAllowed is a list of glob patterns specifying allowed actions.\nEach pattern can match action repositories using wildcards, e.g., \"my-org/*\" or \"*/action-name@*\".", + "items": { + "type": "string" + }, + "type": "array" + }, + "verifiedAllowed": { + "default": false, + "description": "VerifiedAllowed determines whether actions from verified creators are allowed to run.\nVerified creators are trusted partners and organizations with verified domains.", + "type": "boolean" + } + }, + "type": "object", + "additionalProperties": false + }, + "shaPinningRequired": { + "default": false, + "description": "ShaPinningRequired determines whether workflows must reference actions using the commit SHA instead of tags or branches.\nWhen true, improves security by preventing tag manipulation attacks.", + "type": "boolean" + } + }, + "type": "object", + "additionalProperties": false + }, + "codeSecurityConfigurations": { + "description": "CodeSecurityConfigurations lists code security configurations to create and optionally attach to repositories.\nEach configuration defines security features like dependency scanning, secret scanning, and code scanning.\nSee: https://docs.github.com/en/rest/code-security/configurations", + "items": { + "description": "AttachableCodeSecurityConfigurationRef references a CodeSecurityConfiguration CRD and specifies its attachment scope.\nCode security configurations define security settings like dependency scanning, secret scanning, and code scanning.\nSee: https://docs.github.com/en/rest/code-security/configurations", + "properties": { + "attachmentScope": { + "description": "AttachmentScope defines which repositories the code security configuration applies to.\n- \"all\": Apply to all repositories in the organization\n- \"all_without_configurations\": Apply to repositories without an existing configuration\n- \"public\": Apply only to public repositories\n- \"private_or_internal\": Apply only to private and internal repositories\n- \"selected\": Apply only to repositories that explicitly reference this configuration in their AttachedCodeSecurityConfiguration field\nIf not set, the configuration is created but not attached to any repositories.\n\nNote: GitHub's API does not provide a way to retrieve the current attachment scope type.\nThe reconciler ensures functional correctness by comparing the actual list of attached repositories\nto the desired state, not the scope label itself. This means GitHub's UI may display \"selected repositories\"\neven when the scope is set to \"all\" (if all repositories happen to be selected), which is a cosmetic\ndiscrepancy that does not affect the actual security configuration. The reconciler will only re-attach\nif the actual repository attachments differ from what the scope implies.\n\nFor scope \"all_without_configurations\", the attachment is performed unconditionally without\ncomparing repository lists, as there is no reliable way to determine which repositories should\nbe included (repositories without configurations at the time of attachment may have since\nbeen configured). The reconciler will re-attach on every reconciliation for this scope.", + "enum": [ + "all", + "all_without_configurations", + "public", + "private_or_internal", + "selected" + ], + "type": "string" + }, + "name": { + "description": "Name is the name of the referenced CodeSecurityConfiguration CRD.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object", + "additionalProperties": false + }, + "type": "array" + }, + "customProperties": { + "description": "CustomProperties defines custom metadata properties that can be assigned to repositories in the organization.\nThese properties allow you to categorize and add structured metadata to your repositories.\nSee: https://docs.github.com/en/rest/orgs/custom-properties", + "items": { + "description": "OrgCustomProperty defines a custom property for an organization.\nCustom properties allow you to add metadata to repositories in your organization.\nThis is a kubebuilder annotated copy of github.CustomProperty without the source_type (as it is fixed to \"organization\").\nFor the logic to work the json field names must match the ones in github.CustomProperty.\nSee: https://docs.github.com/en/rest/orgs/custom-properties", + "properties": { + "allowedValues": { + "description": "AllowedValues is a list of allowed values for the property.\nThis property is required for ValueType \"single_select\" and \"multi_select\".\nFor the other ValueTypes, it must be empty.", + "items": { + "type": "string" + }, + "maxItems": 200, + "type": "array" + }, + "defaultValue": { + "description": "DefaultValue is the default value for the property.\nThis property must be set if Required is true. It must be empty if Required is false.\nThe allowed format depends on the ValueType.\nFor ValueType \"string\" or \"single_select\", it must be a string. For \"single_select\", it must be one of the AllowedValues.\nFor ValueType \"multi_select\", it must be a JSON array of strings only containing elements of AllowedValues.\nFor ValueType \"true_false\", it must be a string that is either \"true\" or \"false\".", + "properties": { + "value": { + "description": "Value is the default value for properties with ValueType \"string\", \"single_select\", or \"true_false\".\nFor \"true_false\", it must be either \"true\" or \"false\".\nFor \"single_select\", it must be one of the AllowedValues defined in the property.", + "type": "string" + }, + "values": { + "description": "Values is the default value for properties with ValueType \"multi_select\".\nEach value must be one of the AllowedValues defined in the property.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "x-kubernetes-validations": [ + { + "message": "exactly one of the fields in [value values] must be set", + "rule": "[has(self.value),has(self.values)].filter(x,x==true).size() == 1" + } + ], + "additionalProperties": false + }, + "description": { + "description": "Description provides additional information about the purpose and usage of this custom property.", + "type": "string" + }, + "propertyName": { + "description": "PropertyName is the unique name of the custom property.\nMust start with a letter, number, _, $, or # and can only contain letters, numbers, _, $, #, and -.", + "pattern": "^[a-zA-Z0-9_\\$#\\-]+$", + "type": "string" + }, + "required": { + "default": false, + "description": "Required indicates whether this property must be set on all repositories.\nIf true, a DefaultValue must be provided.", + "type": "boolean" + }, + "valueType": { + "description": "ValueType specifies the type of value this property accepts.\n- \"string\": A free-form text value\n- \"single_select\": A single value from a predefined list (requires AllowedValues)\n- \"multi_select\": Multiple values from a predefined list (requires AllowedValues)\n- \"true_false\": A boolean value represented as \"true\" or \"false\"", + "enum": [ + "string", + "single_select", + "multi_select", + "true_false" + ], + "type": "string" + }, + "valuesEditableBy": { + "default": "org_actors", + "description": "ValuesEditableBy determines who can edit the property values on repositories.\n- \"org_actors\": Only organization members can edit values\n- \"org_and_repo_actors\": Both organization and repository members can edit values", + "enum": [ + "org_actors", + "org_and_repo_actors" + ], + "type": "string" + } + }, + "required": [ + "propertyName", + "valueType" + ], + "type": "object", + "additionalProperties": false + }, + "maxItems": 100, + "type": "array" + }, + "description": { + "description": "Description is a human-readable description of the organization.\nThis appears on the organization's GitHub profile page.", + "type": "string" + }, + "githubAppConfig": { + "description": "GitHubAppConfig specifies the GitHub App installation and credentials secret to use for\nauthenticating API requests on behalf of this organization.\nAt least one of GitHubAppConfig or GitHubAppInstallationId must be set.\nIf both are set, GitHubAppConfig takes precedence.", + "properties": { + "credentialsSecretName": { + "description": "CredentialsSecretName is the name of the Kubernetes Secret containing the GitHub App credentials.\nThe secret must contain the keys `app-id` and `private-key` and must reside in the namespace\nconfigured via the APP_CREDENTIALS_SECRET_NAMESPACE environment variable.", + "minLength": 1, + "type": "string" + }, + "installationId": { + "description": "InstallationId is the numeric ID of the GitHub App installation for this organization.\nYou can find this ID in your GitHub App's installation settings or via the GitHub API.", + "format": "int64", + "minimum": 1, + "type": "integer" + } + }, + "required": [ + "credentialsSecretName", + "installationId" + ], + "type": "object", + "additionalProperties": false + }, + "githubAppInstallationId": { + "description": "GitHubAppInstallationId is the numeric ID of the GitHub App installation for this organization.\nThis field is deprecated. Use GitHubAppConfig instead, which also allows specifying which\ncredential secret to use. When only this field is set, the operator falls back to the\nsecret name configured via --app-credentials-secret-name.\nAt least one of GitHubAppInstallationId or GitHubAppConfig must be set.\nIf both are set, GitHubAppConfig takes precedence.", + "format": "int64", + "minimum": 1, + "type": "integer" + }, + "location": { + "description": "Location is the organization's location (e.g., \"Munich, Germany\").\nThis appears on the organization's GitHub profile page.", + "maxLength": 100, + "type": "string" + }, + "login": { + "description": "Login is the GitHub organization login (the unique, immutable identifier on GitHub).\nThis field is optional for backwards compatibility. If not specified, the Name field\nwill be used as both login and display name.\nIt is recommended to explicitly set this field to clearly separate login from display name.", + "maxLength": 39, + "minLength": 1, + "type": "string" + }, + "memberSuffix": { + "default": "", + "description": "MemberSuffix defines a suffix appended to each team member username before matching/adding them on GitHub.\nUseful when GitHub usernames follow a naming convention (e.g. enterprise suffix).\nIs ignored if environment variable GITHUB_MEMBER_SUFFIX is set.", + "maxLength": 100, + "type": "string" + }, + "name": { + "description": "Name is the organization's display name shown on the GitHub profile.\nIf Login is not specified, this field will also be used as the organization login\nfor backwards compatibility.\nAt least one of Login or Name must be specified.", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "plan": { + "default": "enterprise", + "description": "Plan indicates the GitHub plan tier for this organization (enterprise, team, or free).\nDetermines whether Enterprise-only features (e.g., custom properties, runner groups) are reconciled or skipped.", + "enum": [ + "enterprise", + "team", + "free" + ], + "type": "string" + }, + "rulesetPresets": { + "description": "RulesetPresetList references RulesetPreset CRDs that define repository rulesets for this organization.\nRulesets enforce policies like branch protection, required reviews, and status checks.\nSee: https://docs.github.com/en/rest/orgs/rules", + "items": { + "description": "LocalObjectReference contains enough information to let you locate the\nreferenced object inside the same namespace.", + "properties": { + "name": { + "default": "", + "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "type": "string" + } + }, + "type": "object", + "x-kubernetes-map-type": "atomic", + "additionalProperties": false + }, + "type": "array" + }, + "website": { + "description": "Website is the organization's website URL.\nThis appears on the organization's GitHub profile page as a clickable link.", + "maxLength": 255, + "type": "string" + } + }, + "required": [ + "actionsSettings", + "codeSecurityConfigurations", + "description" + ], + "type": "object", + "additionalProperties": false + }, + "status": { + "description": "status defines the observed state of Organization", + "properties": { + "conditions": { + "description": "conditions represent the current state of the Organization resource.\nEach condition has a unique type and reflects the status of a specific aspect of the resource.\n\nStandard condition types include:\n- \"Available\": the resource is fully functional\n- \"Progressing\": the resource is being created or updated\n- \"Degraded\": the resource failed to reach or maintain its desired state\n\nThe status of each condition is one of True, False, or Unknown.", + "items": { + "description": "Condition contains details for one aspect of the current state of this API Resource.", + "properties": { + "lastTransitionTime": { + "description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.", + "format": "date-time", + "type": "string" + }, + "message": { + "description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.", + "maxLength": 32768, + "type": "string" + }, + "observedGeneration": { + "description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.", + "format": "int64", + "minimum": 0, + "type": "integer" + }, + "reason": { + "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.", + "maxLength": 1024, + "minLength": 1, + "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$", + "type": "string" + }, + "status": { + "description": "status of the condition, one of True, False, Unknown.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + }, + "type": { + "description": "type of condition in CamelCase or in foo.example.com/CamelCase.", + "maxLength": 316, + "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$", + "type": "string" + } + }, + "required": [ + "lastTransitionTime", + "message", + "reason", + "status", + "type" + ], + "type": "object", + "additionalProperties": false + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map" + }, + "observedSubResourceGenerations": { + "additionalProperties": { + "format": "int64", + "type": "integer" + }, + "description": "ObservedSubResourceGenerations is a map of sub-resource names to their observed generations.\nKeys are in the format \"/\".\nSubResources are kubernetes resources that are referenced by this Organization and are not managed\nby their own controllers like RuleSetPresets and CodeSecurityConfigurations", + "type": "object" + } + }, + "type": "object", + "additionalProperties": false + } + }, + "required": [ + "spec" + ], + "type": "object" +} diff --git a/schemas/repository_v1alpha1.json b/schemas/repository_v1alpha1.json new file mode 100644 index 0000000..64b4c12 --- /dev/null +++ b/schemas/repository_v1alpha1.json @@ -0,0 +1,448 @@ +{ + "description": "Repository is the Schema for the repositories API", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "description": "spec defines the desired state of Repository", + "properties": { + "about": { + "description": "About contains descriptive information about the repository.", + "properties": { + "description": { + "description": "Description is a short description of the repository displayed on the repository page.", + "maxLength": 1000, + "type": "string" + }, + "topics": { + "description": "Topics is a list of topics (tags) that categorize and help discover the repository.\nTopics appear on the repository page and in GitHub's topic explorer.\nSee: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/classifying-your-repository-with-topics", + "items": { + "description": "Topic represents a repository topic (tag) for categorization.\nSee: https://docs.github.com/en/rest/repos/repos#replace-all-repository-topics", + "properties": { + "name": { + "description": "Name is the topic name.\nTopics must be lowercase and can contain letters, numbers, and hyphens.\nThey must start with a letter or number.", + "maxLength": 50, + "pattern": "^[a-z0-9][a-z0-9-]{0,49}$", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "type": "array" + }, + "website": { + "description": "Website is the URL of the repository's homepage or documentation.\nMust be a valid HTTP or HTTPS URL.", + "maxLength": 200, + "pattern": "^https?://[^\\s]+$", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "accessLevelForExternalWorkflows": { + "default": "none", + "description": "AccessLevelForExternalWorkflows controls access to workflows outside the repository.\n- \"none\": Only workflows in this repository can access actions and reusable workflows\n- \"user\": Workflows in user-owned private repositories can access them\n- \"organization\": Workflows across the organization can access them\n- \"enterprise\": Workflows across the enterprise can access them\nSee: https://docs.github.com/en/rest/actions/permissions", + "enum": [ + "none", + "user", + "organization", + "enterprise" + ], + "type": "string" + }, + "actionsEnabled": { + "default": true, + "description": "ActionsEnabled determines whether this repository can use GitHub Actions.\nThis must be enabled at the organization level for this setting to take effect.\nSee: https://docs.github.com/en/rest/actions/permissions", + "type": "boolean" + }, + "allowedMergeStrategies": { + "default": [ + { + "type": "merge" + }, + { + "type": "rebase" + } + ], + "description": "AllowedMergeStrategies lists the merge strategies allowed for pull requests.\nSee: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges", + "items": { + "description": "MergeStrategy defines an allowed merge strategy for pull requests.\nSee: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/about-merge-methods-on-github", + "properties": { + "type": { + "description": "Type specifies the merge strategy type.\n- \"merge\": Create a merge commit (preserves all commits from the feature branch)\n- \"rebase\": Rebase and merge (rebases commits onto base branch)\n- \"squash\": Squash and merge (combines all commits into a single commit)", + "enum": [ + "merge", + "rebase", + "squash" + ], + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "type": "array" + }, + "archived": { + "default": false, + "description": "Archived marks the repository as archived (read-only).\nArchived repositories cannot receive new issues, pull requests, or commits.\nSee: https://docs.github.com/en/repositories/archiving-a-github-repository/archiving-repositories", + "type": "boolean" + }, + "attachedCodeSecurityConfiguration": { + "description": "AttachedCodeSecurityConfiguration references a CodeSecurityConfiguration to attach to this repository.\nThis is only used when the organization's configuration has \"selected\" attachment scope.\nSee: https://docs.github.com/en/rest/code-security/configurations", + "properties": { + "name": { + "description": "Name is the name of the referenced CodeSecurityConfiguration CRD.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object", + "additionalProperties": false + }, + "autolinksPresets": { + "description": "AutolinksPresetList references AutolinksPreset CRDs to create autolinks for this repository.\nAutolinks automatically convert references (like \"JIRA-123\") into clickable links.\nSee: https://docs.github.com/en/rest/repos/autolinks", + "items": { + "description": "LocalObjectReference contains enough information to let you locate the\nreferenced object inside the same namespace.", + "properties": { + "name": { + "default": "", + "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "type": "string" + } + }, + "type": "object", + "x-kubernetes-map-type": "atomic", + "additionalProperties": false + }, + "type": "array" + }, + "availableActionsRunnerGroups": { + "description": "AvailableActionsRunnerGroups lists runner group names that this repository can use.\nThis is only relevant when the organization's runner groups have \"selected\" visibility.\nSee: https://docs.github.com/en/rest/actions/self-hosted-runner-groups", + "items": { + "type": "string" + }, + "type": "array" + }, + "customProperties": { + "description": "CustomProperties is a list of custom property values to apply to this repository.\nThese properties must be defined in the parent organization's custom properties.\nIf a property is not present in this list, it will be unset (removed) from the repository.\nSee: https://docs.github.com/en/rest/repos/custom-properties", + "items": { + "description": "CustomPropertyValue defines a custom property value for a repository.\nCustom properties are defined at the organization level and applied to repositories.\nIf both Value and Values are empty, the value for the property is considered nil (removes the property).\nFor custom properties of value type \"multi_select\", use Values to specify multiple selections.\nFor all other value types (\"string\", \"single_select\", \"true_false\"), use Value.\nSee: https://docs.github.com/en/rest/repos/custom-properties", + "properties": { + "propertyName": { + "description": "PropertyName is the name of the custom property as defined in the organization.", + "type": "string" + }, + "value": { + "description": "Value is the property value for types \"string\", \"single_select\", and \"true_false\".\nFor \"true_false\", must be \"true\" or \"false\".\nFor \"single_select\", must be one of the allowed values defined in the organization's custom property.", + "type": "string" + }, + "values": { + "description": "Values is the list of selected values for \"multi_select\" type properties.\nEach value must be one of the allowed values defined in the organization's custom property.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "propertyName" + ], + "type": "object", + "x-kubernetes-validations": [ + { + "message": "exactly one of the fields in [value values] must be set", + "rule": "[has(self.value),has(self.values)].filter(x,x==true).size() == 1" + } + ], + "additionalProperties": false + }, + "type": "array" + }, + "defaultBranch": { + "default": "main", + "description": "DefaultBranch is the name of the default branch for the repository.\nThis is the base branch for pull requests and where the repository opens by default.", + "maxLength": 100, + "minLength": 1, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,99}$", + "type": "string" + }, + "deleteBranchOnMerge": { + "default": true, + "description": "DeleteBranchOnMerge automatically deletes head branches after pull requests are merged.\nThis helps keep the repository clean by removing merged feature branches.\nSee: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-the-automatic-deletion-of-branches", + "type": "boolean" + }, + "deployKeys": { + "description": "DeployKeyList defines deploy keys to create for this repository.\nDeploy keys are SSH keys that grant access to a single repository.\nSee: https://docs.github.com/en/rest/deploy-keys/deploy-keys", + "items": { + "description": "DeployKey defines an SSH key for read-only or read-write access to a single repository.\nDeploy keys are commonly used for CI/CD systems and automated deployments.\nSee: https://docs.github.com/en/rest/deploy-keys/deploy-keys", + "properties": { + "key": { + "description": "Key is the public SSH key in OpenSSH format.\nSupported key types are RSA and Ed25519.\nExample: \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...\" or \"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5...\"", + "pattern": "^ssh-(rsa|ed25519) [A-Za-z0-9+/]+={0,3}( [^\\s]+)?$", + "type": "string" + }, + "readOnly": { + "default": true, + "description": "ReadOnly determines the access level for this deploy key.\n- true: Key can only read from the repository (cannot push)\n- false: Key can read and write to the repository (can push commits)", + "type": "boolean" + }, + "title": { + "description": "Title is a descriptive name for the deploy key shown in the repository settings.\nExamples: \"CI/CD Key\", \"Read-Only Deploy Key\", \"Production Server\"", + "type": "string" + } + }, + "required": [ + "key", + "title" + ], + "type": "object", + "additionalProperties": false + }, + "type": "array" + }, + "hasDownloads": { + "default": false, + "description": "HasDownloads enables or disables the Downloads feature for the repository.\nThis feature is deprecated and has been replaced by Releases.", + "type": "boolean" + }, + "hasIssues": { + "default": true, + "description": "HasIssues enables or disables the GitHub Issues feature for the repository.\nWhen enabled, users can create and track issues.", + "type": "boolean" + }, + "hasProjects": { + "default": false, + "description": "HasProjects enables or disables the GitHub Projects (classic) feature for the repository.\nNote: This refers to classic projects, not the newer Projects feature.", + "type": "boolean" + }, + "hasWiki": { + "default": false, + "description": "HasWiki enables or disables the GitHub Wiki feature for the repository.\nWhen enabled, users can create wiki pages for documentation.", + "type": "boolean" + }, + "isTemplate": { + "default": false, + "description": "IsTemplate marks the repository as a template repository.\nTemplate repositories can be used as a starting point for new repositories.\nSee: https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-template-repository", + "type": "boolean" + }, + "mergeCommitMessage": { + "default": "PR_TITLE", + "description": "MergeCommitMessage determines the default message for merge commits.\n- \"PR_BODY\": Use the pull request body\n- \"PR_TITLE\": Use the pull request title\n- \"BLANK\": Use a blank message\nSee: https://docs.github.com/en/rest/repos/repos#update-a-repository", + "enum": [ + "PR_BODY", + "PR_TITLE", + "BLANK" + ], + "type": "string" + }, + "mergeCommitTitle": { + "default": "MERGE_MESSAGE", + "description": "MergeCommitTitle determines the default title for merge commits.\n- \"PR_TITLE\": Use the pull request title\n- \"MERGE_MESSAGE\": Use the default merge message format\nSee: https://docs.github.com/en/rest/repos/repos#update-a-repository", + "enum": [ + "PR_TITLE", + "MERGE_MESSAGE" + ], + "type": "string" + }, + "name": { + "description": "Name is the GitHub repository name.\nRepository names can contain alphanumeric characters, hyphens, underscores, and periods.", + "maxLength": 100, + "minLength": 1, + "pattern": "^[.a-zA-Z0-9][a-zA-Z0-9_.-]{0,99}$", + "type": "string" + }, + "organizationRef": { + "description": "OrganizationRef references the Organization CRD this repository belongs to.", + "properties": { + "name": { + "description": "Name is the name of the referenced Organization CRD.", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "rulesetPresets": { + "description": "RulesetPresetList references RulesetPreset CRDs to apply to this repository.\nThese define branch protection rules, required status checks, and other policies.\nSee: https://docs.github.com/en/rest/repos/rules", + "items": { + "description": "LocalObjectReference contains enough information to let you locate the\nreferenced object inside the same namespace.", + "properties": { + "name": { + "default": "", + "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "type": "string" + } + }, + "type": "object", + "x-kubernetes-map-type": "atomic", + "additionalProperties": false + }, + "type": "array" + }, + "visibility": { + "default": "private", + "description": "Visibility controls who can see the repository.\n- \"public\": Anyone can see the repository\n- \"private\": Only people with explicit access can see the repository\n- \"internal\": Only members of the organization can see the repository (Enterprise only)\nSee: https://docs.github.com/en/rest/repos/repos#create-an-organization-repository", + "enum": [ + "public", + "private", + "internal" + ], + "type": "string" + }, + "webhookIgnorePresets": { + "description": "WebhookIgnorePresetsList references WebhookIgnorePreset CRDs that define webhooks to ignore.\nWebhooks matching these patterns will not be created even if they are in WebhookPresetList.", + "items": { + "description": "LocalObjectReference contains enough information to let you locate the\nreferenced object inside the same namespace.", + "properties": { + "name": { + "default": "", + "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "type": "string" + } + }, + "type": "object", + "x-kubernetes-map-type": "atomic", + "additionalProperties": false + }, + "type": "array" + }, + "webhookPresets": { + "description": "WebhookPresetList references WebhookPreset CRDs to create webhooks for this repository.\nWebhooks send HTTP POST payloads to external services when specific events occur.\nSee: https://docs.github.com/en/rest/webhooks/repos", + "items": { + "description": "LocalObjectReference contains enough information to let you locate the\nreferenced object inside the same namespace.", + "properties": { + "name": { + "default": "", + "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "type": "string" + } + }, + "type": "object", + "x-kubernetes-map-type": "atomic", + "additionalProperties": false + }, + "type": "array" + } + }, + "required": [ + "name", + "organizationRef" + ], + "type": "object", + "additionalProperties": false + }, + "status": { + "description": "status defines the observed state of Repository", + "properties": { + "conditions": { + "description": "conditions represent the current state of the Repository resource.\nEach condition has a unique type and reflects the status of a specific aspect of the resource.\n\nStandard condition types include:\n- \"Available\": the resource is fully functional\n- \"Progressing\": the resource is being created or updated\n- \"Degraded\": the resource failed to reach or maintain its desired state\n\nThe status of each condition is one of True, False, or Unknown.", + "items": { + "description": "Condition contains details for one aspect of the current state of this API Resource.", + "properties": { + "lastTransitionTime": { + "description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.", + "format": "date-time", + "type": "string" + }, + "message": { + "description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.", + "maxLength": 32768, + "type": "string" + }, + "observedGeneration": { + "description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.", + "format": "int64", + "minimum": 0, + "type": "integer" + }, + "reason": { + "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.", + "maxLength": 1024, + "minLength": 1, + "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$", + "type": "string" + }, + "status": { + "description": "status of the condition, one of True, False, Unknown.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + }, + "type": { + "description": "type of condition in CamelCase or in foo.example.com/CamelCase.", + "maxLength": 316, + "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$", + "type": "string" + } + }, + "required": [ + "lastTransitionTime", + "message", + "reason", + "status", + "type" + ], + "type": "object", + "additionalProperties": false + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map" + }, + "id": { + "description": "ID is the repository ID as created by GitHub.", + "format": "int64", + "type": "integer" + }, + "observedSubResourceGenerations": { + "additionalProperties": { + "format": "int64", + "type": "integer" + }, + "description": "ObservedSubResourceGenerations is a map of sub-resource names to their observed generations.\nKeys are in the format \"/\".\nSubResources are kubernetes resources that are referenced by this Repository and are not managed\nby their own controllers like WebhookPresets, RuleSetPresets and the attached CodeSecurityConfiguration", + "type": "object" + }, + "webhooks": { + "additionalProperties": { + "description": "WebhookStatus defines the status of a webhook configured for a repository", + "properties": { + "secretHash": { + "description": "Secret is a hash of the secret used for the webhook", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "description": "Webhooks is a list of webhooks configured for this repository\nthe key is the hash of the configuration", + "type": "object" + } + }, + "type": "object", + "additionalProperties": false + } + }, + "required": [ + "spec" + ], + "type": "object" +} diff --git a/schemas/rulesetpreset_v1alpha1.json b/schemas/rulesetpreset_v1alpha1.json new file mode 100644 index 0000000..c970329 --- /dev/null +++ b/schemas/rulesetpreset_v1alpha1.json @@ -0,0 +1,766 @@ +{ + "description": "RulesetPreset is the Schema for the rulesetpresets API", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "description": "spec defines the desired state of RulesetPreset", + "properties": { + "bypassActors": { + "description": "BypassActors defines actors (users, teams, apps) who can bypass this ruleset.\nBypass actors can perform operations that would otherwise be blocked by the ruleset.\nSee: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets#about-bypass-mode-for-rulesets", + "items": { + "description": "RulesetBypassActor defines an actor (user, team, or integration) who can bypass ruleset enforcement.\nEither ActorID (for direct specification) or ActorSlug (for name-based resolution) must be provided for\nActorTypes \"Integration\" and \"Team\". ActorID must be provided for ActorType \"RepositoryRole\".\nBoth must be empty for ActorType \"DeployKey\".\nSee: https://docs.github.com/en/rest/repos/rules#create-an-organization-repository-ruleset", + "properties": { + "actorId": { + "description": "ActorID is the numeric ID of the bypass actor.\nThis field is mutually exclusive with ActorSlug.", + "format": "int64", + "type": "integer" + }, + "actorSlug": { + "description": "ActorSlug is the slug or name of the actor, which will be resolved to an ID.\nThis field is mutually exclusive with ActorID.\nOnly supported for ActorType \"Integration\" (GitHub Apps) and \"Team\" (organization teams).\nFor Integration, use the app slug (e.g., \"my-github-app\").\nFor Team, use the team slug (e.g., \"platform-engineers\").", + "type": "string" + }, + "actorType": { + "description": "ActorType specifies the type of actor that can bypass the ruleset.\n- \"Integration\": A GitHub App\n- \"OrganizationAdmin\": Organization administrators\n- \"RepositoryRole\": Users with a specific repository role\n- \"Team\": An organization team\n- \"DeployKey\": A deploy key\n- \"EnterpriseOwner\": Enterprise owners (GitHub Enterprise only)", + "enum": [ + "Integration", + "OrganizationAdmin", + "RepositoryRole", + "Team", + "DeployKey", + "EnterpriseOwner" + ], + "type": "string" + }, + "bypassMode": { + "description": "BypassMode determines when and how the actor can bypass the ruleset.\n- \"always\": Actor can always bypass the ruleset\n- \"pull_request\": Actor can bypass only when submitting via pull request", + "enum": [ + "always", + "pull_request" + ], + "type": "string" + } + }, + "required": [ + "actorType" + ], + "type": "object", + "x-kubernetes-validations": [ + { + "message": "at most one of the fields in [actorId actorSlug] may be set", + "rule": "[has(self.actorId),has(self.actorSlug)].filter(x,x==true).size() <= 1" + } + ], + "additionalProperties": false + }, + "maxItems": 100, + "type": "array" + }, + "conditions": { + "description": "Conditions defines which refs are included or excluded in the list of targets for this Ruleset.\nThey also define which Repositories are targeted by Organization-level Rulesets.", + "properties": { + "refName": { + "description": "RefName defines which git refs (branches or tags) a ruleset applies to.", + "minProperties": 1, + "properties": { + "exclude": { + "description": "Exclude defines ref patterns to exempt from the ruleset.\nRefs matching exclude patterns will not be subject to the ruleset rules.\nUseful for exempting release branches or other special refs.", + "items": { + "pattern": "^(~DEFAULT_BRANCH|~ALL|refs/(heads|tags)(/?[*a-zA-Z0-9][a-zA-Z0-9*_.-]*)*)$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "include": { + "description": "Include defines ref patterns that the ruleset applies to.\nPatterns can use wildcards (*) and must start with refs/heads/ (branches) or refs/tags/ (tags).\nUse \"~DEFAULT_BRANCH\" to target the default branch.\nUse \"~ALL\" to target all branches.\nExamples: \"refs/heads/main\", \"refs/heads/feature/*\", \"refs/tags/v*\", \"~DEFAULT_BRANCH\", \"~ALL\"", + "items": { + "pattern": "^(~DEFAULT_BRANCH|~ALL|refs/(heads|tags)(/?[*a-zA-Z0-9][a-zA-Z0-9*_.-]*)*)$", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + } + }, + "type": "object", + "additionalProperties": false + }, + "repositoryName": { + "description": "RepositoryName targets repositories for Organization-level rulesets by their name.\nThe field is ignored for Repository-level rulesets.", + "properties": { + "exclude": { + "description": "Exclude defines repository name patterns to exempt from the ruleset.", + "items": { + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "include": { + "description": "Include defines repository name patterns that the ruleset applies to.\nUse \"~ALL\" to target all repositories. Supports wildcards (*).\nExamples: \"~ALL\", \"my-repo-*\", \"backend-*\"", + "items": { + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "protected": { + "default": false, + "description": "Protected determines whether renaming a targeted repository is prevented.", + "type": "boolean" + } + }, + "required": [ + "include" + ], + "type": "object", + "additionalProperties": false + }, + "repositoryProperty": { + "description": "RepositoryProperty targets repositories for Organization-level rulesets by matching against custom properties.\nThe field is ignored for Repository-level rulesets.", + "properties": { + "exclude": { + "description": "Exclude defines repository property conditions that exempt repositories from the ruleset.\nA repository matching any of the conditions is excluded from the rule.\nThe names of the properties in the slice are validated to be unique.", + "items": { + "description": "RepositoryPropertyTarget defines a single repository property condition for ruleset targeting.\nThe repository must have the specified property set to one of the given values.", + "properties": { + "name": { + "description": "Name is the name of the repository custom property to match against.\nMust match a custom property defined at the organization level.\nNote: restrict name length to be able to validate within budget", + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "propertyValues": { + "description": "PropertyValues is the list of values to match against the custom property.\nThe repository's property value must be one of these values for the condition to match.", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "source": { + "description": "Source defines where the property is defined. Defaults to \"custom\" for organization-defined properties.", + "type": "string" + } + }, + "required": [ + "name", + "propertyValues" + ], + "type": "object", + "additionalProperties": false + }, + "maxItems": 50, + "type": "array", + "x-kubernetes-validations": [ + { + "message": "property names must be unique", + "rule": "self.all(x, self.filter(y, y.name == x.name).size() <= 1)" + } + ] + }, + "include": { + "description": "Include defines repository property conditions that must match for the ruleset to apply.\nA repository must match all included property conditions. The names of the properties in the slice are\nvalidated to be unique.", + "items": { + "description": "RepositoryPropertyTarget defines a single repository property condition for ruleset targeting.\nThe repository must have the specified property set to one of the given values.", + "properties": { + "name": { + "description": "Name is the name of the repository custom property to match against.\nMust match a custom property defined at the organization level.\nNote: restrict name length to be able to validate within budget", + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "propertyValues": { + "description": "PropertyValues is the list of values to match against the custom property.\nThe repository's property value must be one of these values for the condition to match.", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "source": { + "description": "Source defines where the property is defined. Defaults to \"custom\" for organization-defined properties.", + "type": "string" + } + }, + "required": [ + "name", + "propertyValues" + ], + "type": "object", + "additionalProperties": false + }, + "maxItems": 50, + "minItems": 1, + "type": "array", + "x-kubernetes-validations": [ + { + "message": "property names must be unique", + "rule": "self.all(x, self.filter(y, y.name == x.name).size() <= 1)" + } + ] + } + }, + "required": [ + "include" + ], + "type": "object", + "additionalProperties": false + } + }, + "type": "object", + "x-kubernetes-validations": [ + { + "message": "at most one of the fields in [repositoryName repositoryProperty] may be set", + "rule": "[has(self.repositoryName),has(self.repositoryProperty)].filter(x,x==true).size() <= 1" + } + ], + "additionalProperties": false + }, + "enforcement": { + "description": "Enforcement determines whether the ruleset is enforced.\n- \"disabled\": Ruleset is not enforced\n- \"active\": Ruleset is actively enforced; violations block operations\n- \"evaluate\": Ruleset is evaluated but violations only generate warnings", + "enum": [ + "disabled", + "active", + "evaluate" + ], + "type": "string" + }, + "name": { + "description": "Name is the display name of the ruleset shown in the GitHub UI.", + "maxLength": 255, + "minLength": 1, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9\\s\\[\\]*/'_.,~-]*[a-zA-Z0-9\\[\\]]$", + "type": "string" + }, + "rules": { + "description": "Rules defines the specific rules to enforce in this ruleset.", + "properties": { + "branchNamePattern": { + "description": "BranchNamePattern enforces a pattern for branch names.\nUse this to enforce branch naming conventions like \"feature/*\" or \"hotfix/*\".", + "properties": { + "negate": { + "default": false, + "description": "Negate inverts the pattern matching logic.\nWhen true, the rule passes if the pattern does NOT match.\nExample: Use with \"contains\" to prevent certain words in commit messages.", + "type": "boolean" + }, + "operator": { + "description": "Operator defines how the pattern is evaluated.\n- \"starts_with\": String must start with the pattern\n- \"ends_with\": String must end with the pattern\n- \"contains\": String must contain the pattern\n- \"regex\": String must match the pattern as a regular expression", + "enum": [ + "starts_with", + "ends_with", + "contains", + "regex" + ], + "type": "string" + }, + "pattern": { + "description": "Pattern is the pattern to match against.\nFor regex operator, this is a regular expression.\nFor other operators, this is a literal string or substring.", + "maxLength": 1024, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "operator", + "pattern" + ], + "type": "object", + "additionalProperties": false + }, + "commitAuthorEmailPattern": { + "description": "CommitAuthorEmailPattern enforces a pattern for commit author email addresses.\nUse this to ensure commits come from verified email domains.", + "properties": { + "negate": { + "default": false, + "description": "Negate inverts the pattern matching logic.\nWhen true, the rule passes if the pattern does NOT match.\nExample: Use with \"contains\" to prevent certain words in commit messages.", + "type": "boolean" + }, + "operator": { + "description": "Operator defines how the pattern is evaluated.\n- \"starts_with\": String must start with the pattern\n- \"ends_with\": String must end with the pattern\n- \"contains\": String must contain the pattern\n- \"regex\": String must match the pattern as a regular expression", + "enum": [ + "starts_with", + "ends_with", + "contains", + "regex" + ], + "type": "string" + }, + "pattern": { + "description": "Pattern is the pattern to match against.\nFor regex operator, this is a regular expression.\nFor other operators, this is a literal string or substring.", + "maxLength": 1024, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "operator", + "pattern" + ], + "type": "object", + "additionalProperties": false + }, + "commitMessagePattern": { + "description": "CommitMessagePattern enforces a pattern for commit messages.\nUse this to enforce commit message conventions like Conventional Commits.", + "properties": { + "negate": { + "default": false, + "description": "Negate inverts the pattern matching logic.\nWhen true, the rule passes if the pattern does NOT match.\nExample: Use with \"contains\" to prevent certain words in commit messages.", + "type": "boolean" + }, + "operator": { + "description": "Operator defines how the pattern is evaluated.\n- \"starts_with\": String must start with the pattern\n- \"ends_with\": String must end with the pattern\n- \"contains\": String must contain the pattern\n- \"regex\": String must match the pattern as a regular expression", + "enum": [ + "starts_with", + "ends_with", + "contains", + "regex" + ], + "type": "string" + }, + "pattern": { + "description": "Pattern is the pattern to match against.\nFor regex operator, this is a regular expression.\nFor other operators, this is a literal string or substring.", + "maxLength": 1024, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "operator", + "pattern" + ], + "type": "object", + "additionalProperties": false + }, + "committerEmailPattern": { + "description": "CommitterEmailPattern enforces a pattern for committer email addresses.", + "properties": { + "negate": { + "default": false, + "description": "Negate inverts the pattern matching logic.\nWhen true, the rule passes if the pattern does NOT match.\nExample: Use with \"contains\" to prevent certain words in commit messages.", + "type": "boolean" + }, + "operator": { + "description": "Operator defines how the pattern is evaluated.\n- \"starts_with\": String must start with the pattern\n- \"ends_with\": String must end with the pattern\n- \"contains\": String must contain the pattern\n- \"regex\": String must match the pattern as a regular expression", + "enum": [ + "starts_with", + "ends_with", + "contains", + "regex" + ], + "type": "string" + }, + "pattern": { + "description": "Pattern is the pattern to match against.\nFor regex operator, this is a regular expression.\nFor other operators, this is a literal string or substring.", + "maxLength": 1024, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "operator", + "pattern" + ], + "type": "object", + "additionalProperties": false + }, + "copilotReview": { + "description": "CopilotReview automatically requests a GitHub Copilot pull request review\nif the author has access to Copilot code review and their premium requests quota has not reached the limit.", + "properties": { + "reviewDraftPullRequests": { + "default": true, + "description": "ReviewDraftPullRequests configures Copilot to automatically review draft pull requests before they are marked as ready for review.", + "type": "boolean" + }, + "reviewOnPush": { + "default": true, + "description": "ReviewOnPush configures Copilot to automatically review each new push to the pull request.", + "type": "boolean" + } + }, + "type": "object", + "additionalProperties": false + }, + "creation": { + "default": false, + "description": "Creation prevents the creation of matching refs.\nWhen enabled, users cannot create branches or tags matching the ruleset target.", + "type": "boolean" + }, + "deletion": { + "default": false, + "description": "Deletion prevents deletion of matching refs.\nWhen enabled, users cannot delete matching branches or tags.", + "type": "boolean" + }, + "nonFastForward": { + "default": false, + "description": "NonFastForward prevents non-fast-forward updates.\nWhen enabled, only fast-forward pushes are allowed, preventing force pushes.", + "type": "boolean" + }, + "pullRequest": { + "description": "PullRequest defines pull request requirements for merging.\nSee: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches#require-pull-request-reviews-before-merging", + "properties": { + "allowedMergeMethods": { + "description": "AllowedMergeMethods specifies which merge methods are allowed for pull requests.\n- \"squash\": Squash all commits into a single commit\n- \"merge\": Create a merge commit (preserves all commits)\n- \"rebase\": Rebase commits onto the base branch", + "items": { + "enum": [ + "squash", + "merge", + "rebase" + ], + "type": "string" + }, + "type": "array" + }, + "dismissStaleReviewsOnPush": { + "default": false, + "description": "DismissStaleReviewsOnPush automatically dismisses approved reviews when new commits are pushed.\nThis ensures reviewers see the latest changes before approval.", + "type": "boolean" + }, + "requireCodeOwnerReviews": { + "default": false, + "description": "RequireCodeOwnerReviews requires approval from code owners before merging.\nCode owners are defined in a CODEOWNERS file in the repository.\nSee: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners", + "type": "boolean" + }, + "requireLastPushApproval": { + "default": false, + "description": "RequireLastPushApproval requires that the most recent push be approved.\nThis prevents merging if new commits are pushed after the last approval.", + "type": "boolean" + }, + "requiredApprovingReviewCount": { + "description": "RequiredApprovingReviewCount specifies the minimum number of approving reviews required.\nMust be between 1 and 10.", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "requiredReviewThreadResolution": { + "default": false, + "description": "RequiredReviewThreadResolution requires all review comment threads to be resolved before merging.\nThis ensures all feedback is addressed.", + "type": "boolean" + }, + "requiredReviewers": { + "description": "RequiredReviewers forces pull request approval by the configured reviewers\non all pull requests changing files that match the configured file patterns.", + "items": { + "description": "RequiredPullRequestReviewer is the configuration for a required review on all pull request changing files that match\nthe configured file patterns.", + "properties": { + "filePatterns": { + "default": [ + "*" + ], + "description": "FilePatterns are fnmatch syntax patterns that pull request changes are matched against.\nIf a pull request changes any matching file it must be approved by the configured reviewers.\nDefaults to \"*\" representing all files.", + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "minimumApprovals": { + "default": 0, + "description": "MinimumApprovals is the minimum number of approvals required before a matching pull request\ncan be merged. If set to zero, the team will be added to the pull request but approval is optional.\nRequires a non-negative value. Defaults to 0.", + "minimum": 0, + "type": "integer" + }, + "reviewer": { + "description": "Reviewer defines who is required to review.", + "properties": { + "id": { + "description": "ID of the required reviewer. This field is exclusive with Slug.", + "format": "int64", + "type": "integer" + }, + "slug": { + "description": "Slug identifying the required reviewer. This field is exclusive with ID.\nSlug will be resolved to the id during reconciliation.", + "type": "string" + }, + "type": { + "description": "Type of the required reviewer. Currently only Teams are supported.", + "enum": [ + "Team" + ], + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object", + "x-kubernetes-validations": [ + { + "message": "exactly one of the fields in [id slug] must be set", + "rule": "[has(self.id),has(self.slug)].filter(x,x==true).size() == 1" + } + ], + "additionalProperties": false + } + }, + "required": [ + "reviewer" + ], + "type": "object", + "additionalProperties": false + }, + "maxItems": 10, + "type": "array" + } + }, + "required": [ + "allowedMergeMethods" + ], + "type": "object", + "additionalProperties": false + }, + "requiredLinearHistory": { + "default": false, + "description": "RequiredLinearHistory requires branches to have a linear commit history.\nWhen enabled, merge commits are not allowed; only rebasing and fast-forward merges are permitted.", + "type": "boolean" + }, + "requiredSignatures": { + "default": false, + "description": "RequiredSignatures requires commits to be signed with a verified signature.\nWhen enabled, only commits signed with GPG, SSH, or S/MIME are allowed.\nSee: https://docs.github.com/en/authentication/managing-commit-signature-verification", + "type": "boolean" + }, + "requiredStatusChecks": { + "description": "RequiredStatusChecks defines status checks that must pass before merging.\nSee: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches#require-status-checks-before-merging", + "properties": { + "checks": { + "description": "Checks lists the required status checks that must pass.", + "items": { + "description": "StatusCheck defines a required status check that must pass before merging.\nA status check can be provided by a GitHub App or CI/CD integration.\nSee: https://docs.github.com/en/rest/repos/rules#required-status-checks", + "properties": { + "appSlug": { + "description": "AppSlug is the slug of the GitHub App integration providing the status check.\nThis field is mutually exclusive with IntegrationID.\nThe slug will be resolved to the corresponding integration ID.\nOnly supported for GitHub App integrations.\nExample: \"my-ci-app\"", + "type": "string" + }, + "context": { + "description": "Context is the name of the status check as reported by the CI/CD system or app.\nExamples: \"ci/circleci: build\", \"Security Scan\", \"Unit Tests\"", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "integrationId": { + "description": "IntegrationID is the numeric ID of the GitHub App integration providing the status check.\nThis field is mutually exclusive with AppSlug.", + "format": "int64", + "minimum": 1, + "type": "integer" + } + }, + "required": [ + "context" + ], + "type": "object", + "x-kubernetes-validations": [ + { + "message": "at most one of the fields in [integrationId appSlug] may be set", + "rule": "[has(self.integrationId),has(self.appSlug)].filter(x,x==true).size() <= 1" + } + ], + "additionalProperties": false + }, + "maxItems": 100, + "minItems": 1, + "type": "array" + }, + "strictPolicy": { + "default": false, + "description": "StrictPolicy requires branches to be up to date with the base branch before merging.\nWhen enabled, branches must include the latest changes from the base branch.\nThis prevents merge conflicts but may require additional merges/rebases.", + "type": "boolean" + } + }, + "required": [ + "checks" + ], + "type": "object", + "additionalProperties": false + }, + "tagNamePattern": { + "description": "TagNamePattern enforces a pattern for tag names.\nUse this to enforce semantic versioning or other tag naming conventions.", + "properties": { + "negate": { + "default": false, + "description": "Negate inverts the pattern matching logic.\nWhen true, the rule passes if the pattern does NOT match.\nExample: Use with \"contains\" to prevent certain words in commit messages.", + "type": "boolean" + }, + "operator": { + "description": "Operator defines how the pattern is evaluated.\n- \"starts_with\": String must start with the pattern\n- \"ends_with\": String must end with the pattern\n- \"contains\": String must contain the pattern\n- \"regex\": String must match the pattern as a regular expression", + "enum": [ + "starts_with", + "ends_with", + "contains", + "regex" + ], + "type": "string" + }, + "pattern": { + "description": "Pattern is the pattern to match against.\nFor regex operator, this is a regular expression.\nFor other operators, this is a literal string or substring.", + "maxLength": 1024, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "operator", + "pattern" + ], + "type": "object", + "additionalProperties": false + }, + "update": { + "default": false, + "description": "Update prevents updates to matching refs.\nWhen enabled, users cannot push commits to matching branches.", + "type": "boolean" + }, + "workflows": { + "description": "Workflows defines required workflow rules that must pass before merging.\nThis rule type is only effective for organization-level rulesets and is ignored\nwhen the preset is applied at the repository level.\nSee: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets#require-workflows-to-pass-before-merging", + "properties": { + "doNotEnforceOnCreate": { + "default": false, + "description": "DoNotEnforceOnCreate disables enforcement of this rule for newly created refs.\nWhen true, the workflow requirement is not enforced on the first push creating the ref.", + "type": "boolean" + }, + "workflows": { + "description": "Workflows lists the required workflows that must pass.", + "items": { + "description": "RuleWorkflow defines a single required workflow for the workflows rule.\nThe workflow is referenced by its path in a repository. The repository is identified by name\n(resolved to a numeric ID at reconciliation time via the GitHub API).", + "properties": { + "path": { + "description": "Path is the path to the workflow file relative to the repository root.\nExample: \".github/workflows/ci.yaml\"", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "ref": { + "description": "Ref is the git ref (branch, tag, or SHA) to use for the workflow file.\nExample: \"refs/heads/main\"", + "type": "string" + }, + "repositoryName": { + "description": "RepositoryName is the name of the repository containing the workflow.\nMust be a repository within the same organization. The name will be resolved\nto a numeric repository ID at reconciliation time via the GitHub API.", + "maxLength": 100, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "path", + "repositoryName" + ], + "type": "object", + "additionalProperties": false + }, + "maxItems": 100, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "workflows" + ], + "type": "object", + "additionalProperties": false + } + }, + "type": "object", + "additionalProperties": false + }, + "target": { + "default": "branch", + "description": "Target defines which ref types this ruleset applies to.\nThe Target 'repository' is only supported by Organization-level RulesetPresets. Repository-level\nRulesetPresets with Target 'repository' are filtered out (i.e. are not checked nor applied).", + "enum": [ + "branch", + "tag", + "push", + "repository" + ], + "type": "string" + } + }, + "required": [ + "enforcement", + "name", + "rules" + ], + "type": "object", + "additionalProperties": false + }, + "status": { + "description": "status defines the observed state of RulesetPreset", + "properties": { + "conditions": { + "description": "conditions represent the current state of the RulesetPreset resource.\nEach condition has a unique type and reflects the status of a specific aspect of the resource.\n\nStandard condition types include:\n- \"Available\": the resource is fully functional\n- \"Progressing\": the resource is being created or updated\n- \"Degraded\": the resource failed to reach or maintain its desired state\n\nThe status of each condition is one of True, False, or Unknown.", + "items": { + "description": "Condition contains details for one aspect of the current state of this API Resource.", + "properties": { + "lastTransitionTime": { + "description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.", + "format": "date-time", + "type": "string" + }, + "message": { + "description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.", + "maxLength": 32768, + "type": "string" + }, + "observedGeneration": { + "description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.", + "format": "int64", + "minimum": 0, + "type": "integer" + }, + "reason": { + "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.", + "maxLength": 1024, + "minLength": 1, + "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$", + "type": "string" + }, + "status": { + "description": "status of the condition, one of True, False, Unknown.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + }, + "type": { + "description": "type of condition in CamelCase or in foo.example.com/CamelCase.", + "maxLength": 316, + "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$", + "type": "string" + } + }, + "required": [ + "lastTransitionTime", + "message", + "reason", + "status", + "type" + ], + "type": "object", + "additionalProperties": false + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map" + } + }, + "type": "object", + "additionalProperties": false + } + }, + "required": [ + "spec" + ], + "type": "object" +} diff --git a/schemas/team_v1alpha1.json b/schemas/team_v1alpha1.json new file mode 100644 index 0000000..f51ac61 --- /dev/null +++ b/schemas/team_v1alpha1.json @@ -0,0 +1,199 @@ +{ + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "description": "spec defines the desired state of Team", + "properties": { + "description": { + "description": "Description provides additional information about the team's purpose.\nThis appears on the team's page in GitHub.", + "maxLength": 1000, + "type": "string" + }, + "idpGroup": { + "description": "IDPGroup is the name of the Identity Provider group to synchronize with this team.\nThis field is mutually exclusive with Members.\nWhen set, team membership is automatically synchronized from the IDP group.\nSee: https://docs.github.com/en/organizations/organizing-members-into-teams/synchronizing-a-team-with-an-identity-provider-group", + "maxLength": 100, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,99}$", + "type": "string" + }, + "members": { + "description": "Members is a list of GitHub usernames to add to the team.\nThis field is mutually exclusive with IDPGroup.\nWhen set, team membership is managed manually through this list.\nMembers not in this list will be removed from the team.", + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "name": { + "description": "Name is the display name of the team in GitHub.\nGitHub automatically generates a \"slug\" from this name for use in URLs and APIs.", + "maxLength": 100, + "minLength": 1, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.\\-/ ]{0,99}[a-zA-Z0-9]$|^[a-zA-Z0-9]$", + "type": "string" + }, + "notificationSetting": { + "default": "notifications_disabled", + "description": "NotificationSetting controls whether team members receive notifications for the team.\n- \"notifications_disabled\": No one receives notifications.\n- \"notifications_enabled\": Everyone receives notifications when the team is @mentioned.\nSee: https://docs.github.com/en/rest/teams/teams#create-a-team", + "enum": [ + "notifications_disabled", + "notifications_enabled" + ], + "type": "string" + }, + "organizationRefs": { + "description": "OrganizationRefs is a list of Organization CRDs that this team belongs to.\nThe team will be created or updated in all referenced organizations.\nRemoving an organization from this list will delete the team from that organization\nwhile preserving it in other organizations.", + "items": { + "description": "OrganizationRef is a reference to an Organization CRD.", + "properties": { + "name": { + "description": "Name is the name of the referenced Organization CRD.", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "minItems": 1, + "type": "array" + }, + "organizationRoles": { + "description": "OrganizationRoles is a list of organization role names to assign to this team.\nOrganization roles define the permissions the team has within the organization.\nIf not specified, defaults to empty list.\nSet to an empty list to remove all role assignments.\nSee: https://docs.github.com/en/rest/orgs/organization-roles", + "items": { + "type": "string" + }, + "type": "array", + "x-kubernetes-list-type": "set" + }, + "permission": { + "default": "pull", + "description": "Permission specifies the default permission granted to team members for organization repositories.\n- \"pull\": Team members can pull (read) from organization repositories.\n- \"push\": Team members can pull and push (read and write) to organization repositories.\nNote: This is a legacy field. Use organization roles for more fine-grained permissions.\nSee: https://docs.github.com/en/rest/teams/teams#create-a-team", + "enum": [ + "pull", + "push" + ], + "type": "string" + }, + "privacy": { + "default": "closed", + "description": "Privacy controls the visibility of the team within the organization.\n- \"closed\": The team is visible to all members of the organization, but only team members can see team discussions and manage team membership.\n- \"secret\": The team is only visible to organization owners and team members.\nSee: https://docs.github.com/en/rest/teams/teams#create-a-team", + "enum": [ + "closed", + "secret" + ], + "type": "string" + } + }, + "required": [ + "name", + "organizationRefs" + ], + "type": "object", + "x-kubernetes-validations": [ + { + "message": "exactly one of the fields in [idpGroup members] must be set", + "rule": "[has(self.idpGroup),has(self.members)].filter(x,x==true).size() == 1" + } + ], + "additionalProperties": false + }, + "status": { + "description": "status defines the observed state of Team", + "properties": { + "conditions": { + "description": "conditions represent the current state of the Team resource.\nEach condition has a unique type and reflects the status of a specific aspect of the resource.\n\nStandard condition types include:\n- \"Available\": the resource is fully functional\n- \"Progressing\": the resource is being created or updated\n- \"Degraded\": the resource failed to reach or maintain its desired state\n\nThe status of each condition is one of True, False, or Unknown.", + "items": { + "description": "Condition contains details for one aspect of the current state of this API Resource.", + "properties": { + "lastTransitionTime": { + "description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.", + "format": "date-time", + "type": "string" + }, + "message": { + "description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.", + "maxLength": 32768, + "type": "string" + }, + "observedGeneration": { + "description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.", + "format": "int64", + "minimum": 0, + "type": "integer" + }, + "reason": { + "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.", + "maxLength": 1024, + "minLength": 1, + "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$", + "type": "string" + }, + "status": { + "description": "status of the condition, one of True, False, Unknown.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + }, + "type": { + "description": "type of condition in CamelCase or in foo.example.com/CamelCase.", + "maxLength": 316, + "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$", + "type": "string" + } + }, + "required": [ + "lastTransitionTime", + "message", + "reason", + "status", + "type" + ], + "type": "object", + "additionalProperties": false + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map" + }, + "previousOrganizationRefs": { + "description": "PreviousOrganizationRefs tracks the organization references from the last successful reconciliation.\nThis allows the reconciler to detect when organizations are removed from the spec\nand clean up teams from those organizations while preserving them in remaining organizations.", + "items": { + "description": "OrganizationRef is a reference to an Organization CRD.", + "properties": { + "name": { + "description": "Name is the name of the referenced Organization CRD.", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "type": "array" + }, + "slug": { + "description": "Slug is the URL-friendly version of the team name as assigned by GitHub.\nThis slug is used in URLs and API calls. GitHub generates it automatically from the Name field.\nExample: A team named \"Platform Engineers\" might have the slug \"platform-engineers\".", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + } + }, + "required": [ + "spec" + ], + "type": "object" +} diff --git a/schemas/webhookignorepreset_v1alpha1.json b/schemas/webhookignorepreset_v1alpha1.json new file mode 100644 index 0000000..b2663ad --- /dev/null +++ b/schemas/webhookignorepreset_v1alpha1.json @@ -0,0 +1,98 @@ +{ + "description": "WebhookIgnorePreset is the Schema for the webhookignorepresets API", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "description": "spec defines the desired state of WebhookIgnorePreset", + "properties": { + "ignoreURLRegex": { + "description": "IgnoreURLRegex is a regular expression pattern to match against webhook payload URLs.\nWebhooks with URLs matching this pattern will not be created, even if they are\nreferenced in a repository's WebhookPresetList.\nExample: \"^https://deprecated\\\\.example\\\\.com/.*\" to ignore all webhooks to deprecated.example.com", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "status": { + "description": "status defines the observed state of WebhookIgnorePreset", + "properties": { + "conditions": { + "description": "conditions represent the current state of the WebhookIgnorePreset resource.\nEach condition has a unique type and reflects the status of a specific aspect of the resource.\n\nStandard condition types include:\n- \"Available\": the resource is fully functional\n- \"Progressing\": the resource is being created or updated\n- \"Degraded\": the resource failed to reach or maintain its desired state\n\nThe status of each condition is one of True, False, or Unknown.", + "items": { + "description": "Condition contains details for one aspect of the current state of this API Resource.", + "properties": { + "lastTransitionTime": { + "description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.", + "format": "date-time", + "type": "string" + }, + "message": { + "description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.", + "maxLength": 32768, + "type": "string" + }, + "observedGeneration": { + "description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.", + "format": "int64", + "minimum": 0, + "type": "integer" + }, + "reason": { + "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.", + "maxLength": 1024, + "minLength": 1, + "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$", + "type": "string" + }, + "status": { + "description": "status of the condition, one of True, False, Unknown.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + }, + "type": { + "description": "type of condition in CamelCase or in foo.example.com/CamelCase.", + "maxLength": 316, + "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$", + "type": "string" + } + }, + "required": [ + "lastTransitionTime", + "message", + "reason", + "status", + "type" + ], + "type": "object", + "additionalProperties": false + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map" + } + }, + "type": "object", + "additionalProperties": false + } + }, + "required": [ + "spec" + ], + "type": "object" +} diff --git a/schemas/webhookpreset_v1alpha1.json b/schemas/webhookpreset_v1alpha1.json new file mode 100644 index 0000000..6ebb6d9 --- /dev/null +++ b/schemas/webhookpreset_v1alpha1.json @@ -0,0 +1,224 @@ +{ + "description": "WebhookPreset is the Schema for the webhookpresets API", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "description": "spec defines the desired state of WebhookPreset", + "properties": { + "active": { + "default": true, + "description": "Active determines whether the webhook is active and will send events.\nSet to false to temporarily disable the webhook without deleting it.", + "type": "boolean" + }, + "contentType": { + "description": "ContentType specifies the format of the webhook payload.\n- \"json\": Send payload as application/json (recommended)\n- \"form\": Send payload as application/x-www-form-urlencoded\nSee: https://docs.github.com/en/webhooks/webhook-events-and-payloads", + "enum": [ + "json", + "form" + ], + "type": "string" + }, + "events": { + "description": "Events is a list of GitHub event types that trigger this webhook.\nIf empty, the webhook subscribes to all events (\"*\").\nCommon events include \"push\", \"pull_request\", \"issues\", \"release\".\nSee: https://docs.github.com/en/webhooks/webhook-events-and-payloads", + "items": { + "enum": [ + "branch_protection_rule", + "check_run", + "check_suite", + "code_scanning_alert", + "commit_comment", + "create", + "delete", + "dependabot_alert", + "deploy_key", + "deployment", + "deployment_status", + "discussion", + "discussion_comment", + "fork", + "github_app_authorization", + "gollum", + "installation", + "installation_repositories", + "issue_comment", + "issues", + "label", + "marketplace_purchase", + "member", + "membership", + "merge_group", + "meta", + "milestone", + "organization", + "org_block", + "package", + "page_build", + "ping", + "project", + "project_card", + "project_column", + "public", + "pull_request", + "pull_request_review", + "pull_request_review_comment", + "pull_request_review_thread", + "push", + "registry_package", + "release", + "repository", + "repository_dispatch", + "repository_import", + "repository_vulnerability_alert", + "secret_scanning_alert", + "security_advisory", + "sponsorship", + "star", + "status", + "team", + "team_add", + "watch", + "workflow_dispatch", + "workflow_job", + "workflow_run" + ], + "type": "string" + }, + "maxItems": 100, + "minItems": 0, + "type": "array" + }, + "payloadUrl": { + "description": "PayloadURL is the URL that will receive the webhook POST requests.\nMust be a publicly accessible HTTP or HTTPS endpoint.\nGitHub will send HTTP POST requests to this URL when subscribed events occur.", + "maxLength": 2048, + "minLength": 1, + "pattern": "^https?://[a-zA-Z0-9.-]+(:[0-9]+)?(/.*)?$", + "type": "string" + }, + "secret": { + "description": "Secret is a reference to a Kubernetes Secret containing the webhook secret.\nThe webhook secret is used by GitHub to sign webhook payloads.\nYour service can verify this signature to ensure the request came from GitHub.\nThis field takes precedence over SecretValue if both are provided.\nSee: https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries", + "properties": { + "key": { + "description": "Key is the key within the Secret that contains the webhook secret value.", + "maxLength": 250, + "minLength": 1, + "pattern": "^[a-zA-Z0-9.-]+$", + "type": "string" + }, + "name": { + "description": "Name is the name of the Kubernetes Secret containing the webhook secret.", + "maxLength": 250, + "minLength": 1, + "pattern": "^[a-zA-Z0-9.-]+$", + "type": "string" + }, + "namespace": { + "description": "Namespace is the namespace of the Secret.\nIf not specified, the namespace of the WebhookPreset is used.", + "type": "string" + } + }, + "required": [ + "key", + "name" + ], + "type": "object", + "additionalProperties": false + }, + "secretValue": { + "description": "SecretValue is the plaintext value of the webhook secret.\nUse this for simple cases, but Secret (referencing a Kubernetes Secret) is more secure.\nIf both Secret and SecretValue are provided, Secret takes precedence.", + "type": "string" + }, + "sslVerify": { + "default": true, + "description": "SSLVerify enables SSL certificate verification for the webhook endpoint.\nWhen true, GitHub verifies the SSL certificate of the PayloadURL.\nDisable only for testing with self-signed certificates; always enable in production.", + "type": "boolean" + } + }, + "required": [ + "payloadUrl" + ], + "type": "object", + "additionalProperties": false + }, + "status": { + "description": "status defines the observed state of WebhookPreset", + "properties": { + "conditions": { + "description": "conditions represent the current state of the WebhookPreset resource.\nEach condition has a unique type and reflects the status of a specific aspect of the resource.\n\nStandard condition types include:\n- \"Available\": the resource is fully functional\n- \"Progressing\": the resource is being created or updated\n- \"Degraded\": the resource failed to reach or maintain its desired state\n\nThe status of each condition is one of True, False, or Unknown.", + "items": { + "description": "Condition contains details for one aspect of the current state of this API Resource.", + "properties": { + "lastTransitionTime": { + "description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.", + "format": "date-time", + "type": "string" + }, + "message": { + "description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.", + "maxLength": 32768, + "type": "string" + }, + "observedGeneration": { + "description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.", + "format": "int64", + "minimum": 0, + "type": "integer" + }, + "reason": { + "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.", + "maxLength": 1024, + "minLength": 1, + "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$", + "type": "string" + }, + "status": { + "description": "status of the condition, one of True, False, Unknown.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + }, + "type": { + "description": "type of condition in CamelCase or in foo.example.com/CamelCase.", + "maxLength": 316, + "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$", + "type": "string" + } + }, + "required": [ + "lastTransitionTime", + "message", + "reason", + "status", + "type" + ], + "type": "object", + "additionalProperties": false + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map" + } + }, + "type": "object", + "additionalProperties": false + } + }, + "required": [ + "spec" + ], + "type": "object" +}