Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 38 additions & 0 deletions api/v1alpha1/organization_methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,41 @@ func (o *OrgCustomPropertyDefaultValue) GetValues() []string {
}
return o.Values
}

// GetLogin returns the effective login for this organization.
// If Login is explicitly set, it returns Login. Otherwise, it returns Name.
func (o *Organization) GetLogin() string {
if o == nil {
return ""
}
if o.Spec.Login != "" {
return o.Spec.Login
}
return o.Spec.Name
}

// GetDisplayName returns the effective display name for this organization.
// If both Login and Name are set, Name is the display name.
// If only Login is set, Login is used as display name.
// If only Name is set, Name is used as both login and display name.
func (o *Organization) GetDisplayName() string {
if o == nil {
return ""
}
if o.Spec.Login != "" && o.Spec.Name != "" {
return o.Spec.Name
}
if o.Spec.Login != "" && o.Spec.Name == "" {
return o.Spec.Login
}
return o.Spec.Name
}

// IsUsingLegacyNameField returns true if only the Name field is set (backwards compatibility mode).
// This is used to generate deprecation warnings.
func (o *Organization) IsUsingLegacyNameField() bool {
if o == nil {
return false
}
return o.Spec.Login == "" && o.Spec.Name != ""
}
35 changes: 28 additions & 7 deletions api/v1alpha1/organization_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,14 +279,23 @@ type OrganizationSpec struct {
// The following markers will use OpenAPI v3 schema to validate the value
// More info: https://book.kubebuilder.io/reference/markers/crd-validation.html

// Name is the GitHub organization name (also known as the organization login).
// This is the unique identifier for the organization on GitHub.
// Login is the GitHub organization login (the unique, immutable identifier on GitHub).
// This field is optional for backwards compatibility. If not specified, the Name field
// will be used as both login and display name.
// It is recommended to explicitly set this field to clearly separate login from display name.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=100
// +kubebuilder:validation:Pattern=`^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,99}$`
// +kubebuilder:validation:Required
// +kubebuilder:validation:Type=string
Name string `json:"name"`
// +kubebuilder:validation:MaxLength=39
// +optional
Login string `json:"login,omitempty"`

// Name is the organization's display name shown on the GitHub profile.
// If Login is not specified, this field will also be used as the organization login
// for backwards compatibility.
// At least one of Login or Name must be specified.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=255
// +optional
Name string `json:"name,omitempty"`

// GitHubAppInstallationId is the numeric ID of the GitHub App installation for this organization.
// This is used to authenticate API requests to GitHub. You can find this ID in your GitHub App's
Expand Down Expand Up @@ -320,6 +329,18 @@ type OrganizationSpec struct {
// This appears on the organization's GitHub profile page.
Description string `json:"description"`

// Location is the organization's location (e.g., "Munich, Germany").
// This appears on the organization's GitHub profile page.
// +kubebuilder:validation:MaxLength=100
// +optional
Location string `json:"location,omitempty"`

// Website is the organization's website URL.
// This appears on the organization's GitHub profile page as a clickable link.
// +kubebuilder:validation:MaxLength=255
// +optional
Website string `json:"website,omitempty"`

// Plan indicates the GitHub plan tier for this organization (enterprise, team, or free).
// Determines whether Enterprise-only features (e.g., custom properties, runner groups) are reconciled or skipped.
// +kubebuilder:validation:Enum=enterprise;team;free
Expand Down
31 changes: 26 additions & 5 deletions config/crd/bases/github.interhyp.de_organizations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -325,13 +325,29 @@ spec:
format: int64
minimum: 1
type: integer
name:
location:
description: |-
Name is the GitHub organization name (also known as the organization login).
This is the unique identifier for the organization on GitHub.
Location is the organization's location (e.g., "Munich, Germany").
This 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).
This field is optional for backwards compatibility. If not specified, the Name field
will be used as both login and display name.
It is recommended to explicitly set this field to clearly separate login from display name.
maxLength: 39
minLength: 1
type: string
name:
description: |-
Name is the organization's display name shown on the GitHub profile.
If Login is not specified, this field will also be used as the organization login
for backwards compatibility.
At least one of Login or Name must be specified.
maxLength: 255
minLength: 1
pattern: ^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,99}$
type: string
plan:
default: enterprise
Expand Down Expand Up @@ -365,12 +381,17 @@ spec:
type: object
x-kubernetes-map-type: atomic
type: array
website:
description: |-
Website is the organization's website URL.
This appears on the organization's GitHub profile page as a clickable link.
maxLength: 255
type: string
required:
- actionsSettings
- codeSecurityConfigurations
- description
- githubAppInstallationId
- name
type: object
status:
description: status defines the observed state of Organization
Expand Down
4 changes: 4 additions & 0 deletions config/samples/github_v1alpha1_organization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ metadata:
app.kubernetes.io/managed-by: kustomize
name: sample-org
spec:
login: sample-org
name: "Sample Organization"
description: "GitHub Sample Organization"
location: "Munich, Germany"
website: "https://example.com"
githubAppCredentials:
secretRef:
name: sample-org-app-credentials
5 changes: 4 additions & 1 deletion docs/techdocs/crds.md
Original file line number Diff line number Diff line change
Expand Up @@ -592,13 +592,16 @@ _Appears in:_

| Field | Description | Default | Validation |
| --- | --- | --- | --- |
| `name` _string_ | Name is the GitHub organization name (also known as the organization login).<br />This is the unique identifier for the organization on GitHub. | | MaxLength: 100 <br />MinLength: 1 <br />Pattern: `^[a-zA-Z0-9][a-zA-Z0-9_.-]\{0,99\}$` <br />Required: \{\} <br />Type: string <br /> |
| `login` _string_ | Login is the GitHub organization login (the unique, immutable identifier on GitHub).<br />This field is optional for backwards compatibility. If not specified, the Name field<br />will be used as both login and display name.<br />It is recommended to explicitly set this field to clearly separate login from display name. | | MaxLength: 39 <br />MinLength: 1 <br />Optional: \{\} <br /> |
| `name` _string_ | Name is the organization's display name shown on the GitHub profile.<br />If Login is not specified, this field will also be used as the organization login<br />for backwards compatibility.<br />At least one of Login or Name must be specified. | | MaxLength: 255 <br />MinLength: 1 <br />Optional: \{\} <br /> |
| `githubAppInstallationId` _integer_ | GitHubAppInstallationId is the numeric ID of the GitHub App installation for this organization.<br />This is used to authenticate API requests to GitHub. You can find this ID in your GitHub App's<br />installation settings or via the GitHub API. | | Minimum: 1 <br />Required: \{\} <br /> |
| `customProperties` _[OrgCustomProperty](#orgcustomproperty) array_ | CustomProperties defines custom metadata properties that can be assigned to repositories in the organization.<br />These properties allow you to categorize and add structured metadata to your repositories.<br />See: https://docs.github.com/en/rest/orgs/custom-properties | | MaxItems: 100 <br /> |
| `actionsSettings` _[ActionsSettings](#actionssettings)_ | ActionsSettings configures GitHub Actions permissions and behavior for the organization.<br />This includes which repositories can use Actions, which actions are allowed, and runner group configurations.<br />See: https://docs.github.com/en/rest/actions/permissions | | |
| `codeSecurityConfigurations` _[AttachableCodeSecurityConfigurationRef](#attachablecodesecurityconfigurationref) array_ | CodeSecurityConfigurations lists code security configurations to create and optionally attach to repositories.<br />Each configuration defines security features like dependency scanning, secret scanning, and code scanning.<br />See: https://docs.github.com/en/rest/code-security/configurations | | |
| `rulesetPresets` _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#localobjectreference-v1-core) array_ | RulesetPresetList references RulesetPreset CRDs that define repository rulesets for this organization.<br />Rulesets enforce policies like branch protection, required reviews, and status checks.<br />See: https://docs.github.com/en/rest/orgs/rules | | |
| `description` _string_ | Description is a human-readable description of the organization.<br />This appears on the organization's GitHub profile page. | | |
| `location` _string_ | Location is the organization's location (e.g., "Munich, Germany").<br />This appears on the organization's GitHub profile page. | | MaxLength: 100 <br />Optional: \{\} <br /> |
| `website` _string_ | Website is the organization's website URL.<br />This appears on the organization's GitHub profile page as a clickable link. | | MaxLength: 255 <br />Optional: \{\} <br /> |
| `plan` _string_ | Plan indicates the GitHub plan tier for this organization (enterprise, team, or free).<br />Determines whether Enterprise-only features (e.g., custom properties, runner groups) are reconciled or skipped. | enterprise | Enum: [enterprise team free] <br />Optional: \{\} <br /> |


Expand Down
33 changes: 30 additions & 3 deletions internal/mapper/github_org_mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,46 @@ import (
)

func OrgToGithubOrg(organization *v1alpha1.Organization) *github.Organization {
return &github.Organization{
Name: &organization.Spec.Name,
displayName := organization.GetDisplayName()
login := organization.GetLogin()
ghOrg := &github.Organization{
Login: &login,
Name: &displayName,
Description: &organization.Spec.Description,
}

if organization.Spec.Location != "" {
ghOrg.Location = &organization.Spec.Location
}
if organization.Spec.Website != "" {
ghOrg.Blog = &organization.Spec.Website
}

return ghOrg
}

func OrgDiffers(org *v1alpha1.Organization, githubOrg github.Organization) bool {
if org.Spec.Name != githubOrg.GetName() {
expectedLogin := org.GetLogin()
if expectedLogin != githubOrg.GetLogin() {
return true
}

expectedDisplayName := org.GetDisplayName()
if expectedDisplayName != githubOrg.GetName() {
return true
}

if org.Spec.Description != githubOrg.GetDescription() {
return true
}

if org.Spec.Location != githubOrg.GetLocation() {
return true
}

if org.Spec.Website != githubOrg.GetBlog() {
return true
}

return false
}
Loading
Loading