Skip to content

Latest commit

 

History

History
280 lines (231 loc) · 6.87 KB

File metadata and controls

280 lines (231 loc) · 6.87 KB

Getting started

Prerequisites

  • Kubernetes 1.30 or newer
  • Helm 3 with OCI registry support
  • kubectl
  • either a GitHub token or an installed GitHub App with access to the target organization and the resources that the operator will manage

Use a disposable repository or organization while evaluating destructive deletion policies.

Install the operator

helm upgrade --install github-platform-operator \
  oci://ghcr.io/pierinho13/charts/github-platform-operator \
  --version 0.1.0 \
  --namespace github-platform-operator-system \
  --create-namespace

Check the installation:

kubectl rollout status \
  deployment/github-platform-operator \
  --namespace github-platform-operator-system

kubectl get crd | grep github.k8sready.com

The Helm chart installs these resources:

githubproviderconfigs.github.k8sready.com
githuborganizationmembers.github.k8sready.com
githubteams.github.k8sready.com
githubteammemberships.github.k8sready.com
githubrepositories.github.k8sready.com
githubrepositoryrulesets.github.k8sready.com
githubrepositoryteamaccesses.github.k8sready.com
githubrepositorycollaborators.github.k8sready.com
githubenvironments.github.k8sready.com
githubactionssecrets.github.k8sready.com
githubactionsvariables.github.k8sready.com

Configure GitHub credentials

A provider must configure exactly one authentication method:

  • an existing GitHub token through credentials.secretRef
  • a GitHub App installation through credentials.githubApp

Personal access token

Create a Kubernetes Secret containing the GitHub token:

kubectl create secret generic github-credentials \
  --namespace default \
  --from-literal=token="${GITHUB_TOKEN}"

Create a cluster-scoped GitHubProviderConfig:

apiVersion: github.k8sready.com/v1alpha1
kind: GitHubProviderConfig
metadata:
  name: default
spec:
  organization: k8sready
  apiURL: https://api.github.com
  credentials:
    secretRef:
      namespace: default
      name: github-credentials
      key: token
kubectl apply -f provider.yaml
kubectl get ghprovider default

GitHub App installation

Create a Secret from the PEM private key downloaded for the GitHub App:

kubectl create secret generic github-app-credentials \
  --namespace github-platform-operator-system \
  --from-file=private-key.pem=/path/to/github-app.private-key.pem

Create the provider:

apiVersion: github.k8sready.com/v1alpha1
kind: GitHubProviderConfig
metadata:
  name: github-app
spec:
  organization: k8sready
  apiURL: https://api.github.com
  credentials:
    githubApp:
      appID: Iv1.REPLACE_ME
      installationID: 12345678
      privateKeySecretRef:
        namespace: github-platform-operator-system
        name: github-app-credentials
        key: private-key.pem

appID accepts the GitHub App client ID or numeric app ID. The operator creates short-lived installation access tokens and refreshes them before expiration. PKCS#1 and PKCS#8 RSA private keys are supported.

For GitHub Enterprise Server, set spec.apiURL to the REST API base URL, for example:

apiURL: https://github.example.com/api/v3

Manage organization membership and teams

Organization membership and team management require GitHub organization Members: write permission.

Create a team, ensure a user belongs to the organization and assign that user to the team:

apiVersion: github.k8sready.com/v1alpha1
kind: GitHubOrganizationMember
metadata:
  name: octocat
  namespace: default
spec:
  providerConfigRef: default
  username: octocat
  role: member
  deletionPolicy: Orphan
---
apiVersion: github.k8sready.com/v1alpha1
kind: GitHubTeam
metadata:
  name: platform
  namespace: default
spec:
  providerConfigRef: default
  name: Platform
  privacy: closed
  deletionPolicy: Orphan
---
apiVersion: github.k8sready.com/v1alpha1
kind: GitHubTeamMembership
metadata:
  name: platform-octocat
  namespace: default
spec:
  teamRef:
    name: platform
  username: octocat
  role: member
  deletionPolicy: Orphan
kubectl apply -f organization-access.yaml
kubectl get ghorgmember,ghteam,ghteammember -A

A new organization or team member can remain pending until the GitHub invitation is accepted.

Create or adopt a repository

apiVersion: github.k8sready.com/v1alpha1
kind: GitHubRepository
metadata:
  name: example-repository
  namespace: default
spec:
  providerConfigRef: default
  name: example-repository
  visibility: private
  deletionPolicy: Orphan
kubectl apply -f repository.yaml
kubectl wait \
  --for=condition=Ready \
  ghrepo/example-repository \
  --timeout=90s

If the repository already exists in the provider organization, the operator adopts it. Optional fields that are omitted remain unmanaged and retain their existing GitHub values.

Inspect the observed state:

kubectl get ghrepo example-repository
kubectl get ghrepo example-repository -o yaml

Protect the repository with a ruleset

Create a disabled ruleset first so its payload and status can be inspected without enforcing it immediately:

apiVersion: github.k8sready.com/v1alpha1
kind: GitHubRepositoryRuleset
metadata:
  name: example-repository-protect-main
  namespace: default
spec:
  repositoryRef:
    name: example-repository
  name: protect-main
  target: branch
  enforcement: disabled
  bypassActors:
    - actorType: Team
      teamSlug: platform
      bypassMode: always
  conditions:
    refName:
      include:
        - "~DEFAULT_BRANCH"
      exclude: []
  rules:
    - type: deletion
    - type: non_fast_forward
  deletionPolicy: Orphan
kubectl apply -f ruleset.yaml
kubectl wait \
  --for=condition=Ready \
  ghruleset/example-repository-protect-main \
  --timeout=90s
kubectl get ghruleset example-repository-protect-main -o yaml

After validating the observed state, activate it:

kubectl patch ghruleset example-repository-protect-main \
  --type merge \
  -p '{"spec":{"enforcement":"active"}}'

The operator resolves team slugs and usernames to numeric GitHub actor IDs. A GitHub App or fine-grained token using teamSlug needs organization Members: read permission in addition to the permissions required to manage rulesets. Classic personal access tokens need read:org. Existing actorID manifests remain valid.

GitHub may return 403 when the repository or organization plan does not support rulesets. Testing against a disposable repository is recommended.

Next steps