|
4 | 4 |
|
5 | 5 |      |
6 | 6 |
|
7 | | - |
8 | 7 | Does the "GH" in "ghops" stand for GitHub? Maybe, maybe not. Maybe it stands for "ghost hops" 👻🍺 or "Git Happyness". |
9 | 8 |
|
10 | | -All we know is that this is a Kubernetes operator to manage stuff on GitHub. |
| 9 | +All we know is that this is a Kubernetes operator to manage resources on GitHub. |
11 | 10 |
|
12 | 11 | ## Description |
13 | 12 |
|
14 | 13 | ### Supported resources |
15 | 14 |
|
16 | | -- DeployKey: A GitHub deploy key for a repository. |
| 15 | +- `DeployKey`: A GitHub deploy key for a repository. |
17 | 16 |
|
18 | 17 | ## Deploy the operator |
19 | 18 |
|
20 | 19 | ### Prerequisites |
21 | 20 |
|
22 | | -- kubectl version v1.11.3+. |
| 21 | +- `kubectl` version v1.11.3+ (or a reasonably recent client compatible with your cluster). |
23 | 22 | - Access to a Kubernetes v1.11.3+ cluster. |
24 | 23 |
|
25 | | -### Create the secret |
| 24 | +### Create the GitHub credentials secret |
| 25 | + |
| 26 | +This operator expects a Kubernetes secret that provides a GitHub access token used to call the GitHub API. |
26 | 27 |
|
27 | | -> This secret is used to authenticate with GitHub. |
| 28 | +1. Create a GitHub fine-grained personal access token with the following repository permissions (scope as needed for the target repositories/organization): |
| 29 | + - Repository: Read metadata |
| 30 | + - Repository: Read and write administration |
28 | 31 |
|
29 | | -1. Create a GitHub fine grained access token with the following permissions (to all your repositories or to all repositories in the organization): |
30 | | - - Repository read metadata |
31 | | - - Repository read and write administration |
| 32 | +2. Create the Kubernetes secret in the namespace where the operator expects it (example: `ghops-system`): |
32 | 33 |
|
33 | | -2. Create the secret in the `ghops-system` namespace: |
| 34 | +```sh |
| 35 | +kubectl create namespace ghops-system || true |
| 36 | +kubectl create secret generic -n ghops-system ghops --from-literal=GITHUB_TOKEN=<your-github-token> |
| 37 | +``` |
34 | 38 |
|
35 | | - ```sh |
36 | | - kubectl create secret generic -n ghops-system ghops --from-literal=GITHUB_TOKEN=<your-github-token> |
37 | | - ``` |
| 39 | +Note: If you deploy into a different namespace update the manifests or the operator configuration accordingly. |
38 | 40 |
|
39 | 41 | ### Deploy the full operator |
40 | 42 |
|
41 | | -> This includes the CRDs, RBAC, and the controller itself. |
| 43 | +This repository contains manifests that install CRDs, RBAC and the controller. |
42 | 44 |
|
43 | 45 | ```sh |
44 | | -# Deploy the latest version |
| 46 | +# Deploy the latest version from the repository |
45 | 47 | kubectl apply -f https://raw.githubusercontent.com/odit-services/ghops/main/config/deployment/full.yaml |
46 | 48 |
|
47 | | -# Deploy a specific version |
| 49 | +# Or deploy a specific tag |
48 | 50 | kubectl apply -f https://raw.githubusercontent.com/odit-services/ghops/<tag>/config/deployment/full.yaml |
49 | 51 | ``` |
50 | 52 |
|
51 | | -## Getting started with the development |
| 53 | +## Development |
52 | 54 |
|
53 | 55 | ### Local prerequisites |
54 | 56 |
|
55 | | -- go version v1.25.0+ |
56 | | -- docker version 17.03+. |
57 | | -- kubectl version v1.11.3+. |
58 | | -- Access to a Kubernetes v1.11.3+ cluster. |
| 57 | +- Go 1.25.0+ |
| 58 | +- Docker (for building images) |
| 59 | +- `kubectl` and access to a Kubernetes cluster (kind / minikube / remote cluster) |
| 60 | + |
| 61 | +### Build and push images |
59 | 62 |
|
60 | | -### To deploy on the cluster |
| 63 | +This project includes Make targets for building and publishing images. |
61 | 64 |
|
62 | | -**Build and push your image to the location specified by `IMG`:** |
| 65 | +Single-arch (build for the host architecture): |
63 | 66 |
|
64 | 67 | ```sh |
65 | | -# Single Arch |
66 | 68 | make docker-build docker-push IMG=ghcr.io/odit-services/ghops:tag |
67 | | - |
68 | | -# Multi Arch |
69 | | -make docker-build-multiarch IMG=ghcr.io/odit-services/ghops:tag |
70 | 69 | ``` |
71 | 70 |
|
72 | | -**NOTE:** This image ought to be published in the personal registry you specified. |
73 | | -And it is required to have access to pull the image from the working environment. |
74 | | -Make sure you have the proper permission to the registry if the above commands don’t work. |
75 | | - |
76 | | -**Install the CRDs into the cluster:** |
| 71 | +Multi-arch (build for linux/amd64 and linux/arm64): |
77 | 72 |
|
78 | 73 | ```sh |
79 | | -make install |
| 74 | +make docker-build-multiarch IMG=ghcr.io/odit-services/ghops:tag |
80 | 75 | ``` |
81 | 76 |
|
82 | | -**Deploy the Manager to the cluster with the image specified by `IMG`:** |
| 77 | +Important note about multi-arch builds and QEMU: |
| 78 | +- If you are building multi-arch images on a host that is not amd64 (for example an Apple Silicon / arm64 host) and you request linux/amd64 images, Docker will use QEMU emulation. The Go runtime (and other native toolchains) can crash under incorrect or unregistered QEMU binfmt support and you'll see runtime panics like `fatal error: taggedPointerPack` during `go mod download`. |
83 | 79 |
|
84 | | -```sh |
85 | | -make deploy IMG=ghcr.io/odit-services/ghops:tag |
86 | | -``` |
87 | | - |
88 | | -> **NOTE**: If you encounter RBAC errors, you may need to grant yourself cluster-admin |
89 | | -privileges or be logged in as admin. |
| 80 | +If you see such a panic in CI (or locally when building inside an emulated image), resolve it by either: |
90 | 81 |
|
91 | | -**Create instances of your solution** |
92 | | -You can apply the samples (examples) from the config/sample: |
| 82 | +1. Registering QEMU/binfmt on the host (self-hosted runner) once with a privileged container: |
93 | 83 |
|
94 | | -```sh |
95 | | -kubectl apply -k config/samples/ |
| 84 | +```powershell |
| 85 | +# Run on the runner host (PowerShell) |
| 86 | +docker run --rm --privileged multiarch/qemu-user-static --reset -p yes |
96 | 87 | ``` |
97 | 88 |
|
98 | | ->**NOTE**: Ensure that the samples has default values to test it out. |
| 89 | +2. Building on a native amd64 runner instead of relying on emulation (for CI use `runs-on: ubuntu-latest` or another amd64 runner). |
99 | 90 |
|
100 | | -### To uninstall |
| 91 | +3. Building only for the host's architecture (remove the linux/amd64 platform when on arm64 hosts). |
101 | 92 |
|
102 | | -**Delete the instances (CRs) from the cluster:** |
| 93 | +Either registering binfmt on the host or using a native builder will prevent the Go runtime emulation panic. |
103 | 94 |
|
104 | | -```sh |
105 | | -kubectl delete -k config/samples/ |
106 | | -``` |
| 95 | +### Buildx and caching (CI) |
107 | 96 |
|
108 | | -**Delete the APIs(CRDs) from the cluster:** |
| 97 | +The included GitHub Actions workflow uses `docker/setup-qemu-action` and `docker/setup-buildx-action` then `docker/build-push-action` with `platforms:` set to `linux/amd64,linux/arm64`. If you run this on a self-hosted runner you must ensure the runner host has QEMU/binfmt registered (see above) or run the workflow on an AMD64 runner. |
109 | 98 |
|
110 | | -```sh |
111 | | -make uninstall |
112 | | -``` |
| 99 | +### Run the operator locally (development mode) |
113 | 100 |
|
114 | | -**UnDeploy the controller from the cluster:** |
| 101 | +To run the controller locally against a cluster (useful for debugging): |
115 | 102 |
|
116 | 103 | ```sh |
117 | | -make undeploy |
| 104 | +# Run the manager locally (points to local kubeconfig) |
| 105 | +make run |
118 | 106 | ``` |
119 | 107 |
|
120 | | -## Contributing |
| 108 | +This will build the binary and run the controller using the local kubeconfig context. |
121 | 109 |
|
122 | | -Feel free to contribute to this project by following the steps below: |
| 110 | +### Tests |
123 | 111 |
|
124 | | -1. Fork the repository |
125 | | -2. Create a new branch (git checkout -b feat/some-feature) |
126 | | -3. Make changes |
127 | | -4. Commit your changes (git commit -am 'Add some feature') |
128 | | -5. Push to the branch (git push origin feat/some-feature) |
129 | | -6. Create a new Pull Request |
| 112 | +- Unit tests (Go): `go test ./...` |
| 113 | +- Integration / e2e: see `test/e2e` and the `Makefile` targets. E2E tests assume a Kubernetes test environment is available. |
130 | 114 |
|
131 | | -All new features and bug fixes should have associated tests. |
| 115 | +## Troubleshooting |
132 | 116 |
|
133 | | -**NOTE:** Run `make help` for more information on all potential `make` targets |
| 117 | +- QEMU / `taggedPointerPack` runtime panic during `go mod download` while building an amd64 image on an arm64 host: register QEMU on the runner host or use a native amd64 runner (see the QEMU note above). |
| 118 | +- Image pull / RBAC issues: ensure the operator service account has the correct RBAC permissions and that the image is published in a registry accessible to your cluster. |
134 | 119 |
|
135 | | -More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html) |
| 120 | +## Examples / Samples |
136 | 121 |
|
137 | | -## License |
| 122 | +Sample CRs are available under `config/samples/` — apply them to create `DeployKey` resources for testing. |
138 | 123 |
|
139 | | -Copyright 2025. |
| 124 | +```sh |
| 125 | +kubectl apply -k config/samples/ |
| 126 | +``` |
140 | 127 |
|
141 | | -Licensed under the Apache License, Version 2.0 (the "License"); |
142 | | -you may not use this file except in compliance with the License. |
143 | | -You may obtain a copy of the License at |
| 128 | +## Contributing |
| 129 | + |
| 130 | +Contributions are welcome. Typical workflow: |
144 | 131 |
|
145 | | - http://www.apache.org/licenses/LICENSE-2.0 |
| 132 | +1. Fork the repository |
| 133 | +2. Create a branch (e.g. `git checkout -b feat/some-feature`) |
| 134 | +3. Implement and test your changes |
| 135 | +4. Commit and push your branch |
| 136 | +5. Open a pull request |
146 | 137 |
|
147 | | -Unless required by applicable law or agreed to in writing, software |
148 | | -distributed under the License is distributed on an "AS IS" BASIS, |
149 | | -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
150 | | -See the License for the specific language governing permissions and |
151 | | -limitations under the License. |
| 138 | +Please include tests for new features or bug fixes and make sure linters pass (`make lint` / CI). |
0 commit comments