Skip to content

Commit 7e41838

Browse files
Proposal: Automating maintenance via tooling and actions
1 parent 8ec703e commit 7e41838

File tree

1 file changed

+305
-0
lines changed

1 file changed

+305
-0
lines changed

designs/update_action.md

Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
| Authors | Creation Date | Status | Extra |
2+
|-----------------|---------------|-------------|-------|
3+
| @camilamacedo86 | 2024-11-07 | Implementable | - |
4+
5+
# Proposal: Automating maintenance via tooling and actions
6+
7+
Kubebuilder is widely used for developing Kubernetes operators, offering a standardized scaffold for projects.
8+
However, as the ecosystem evolves, keeping projects up-to-date becomes challenging due to:
9+
10+
- **Manual re-scaffolding processes**: These are time-intensive and error-prone.
11+
- **Increased risk of outdated configurations**: This leads to security vulnerabilities or incompatibility with modern practices.
12+
13+
This proposal introduces a tool that can be called via workflows like GitHub Action to handle updates
14+
for projects created with Kubebuilder. When a new version of Kubebuilder is released, it would be easier
15+
to upgrade projects, as users would receive a pull request with necessary changes while preserving customizations.
16+
17+
## Example
18+
19+
### Using GitHub Actions:
20+
21+
1. A user creates a project with Kubebuilder `v4.4`.
22+
2. When Kubebuilder `v4.5` is released, a pull request is automatically created.
23+
3. The pull request includes updates to the scaffold while preserving the user’s customizations, ready for review and merging.
24+
25+
### Using the Tool Locally:
26+
27+
1. A user creates a project with Kubebuilder `v4.4`.
28+
2. When Kubebuilder `v4.5` is released, the user runs the tool locally.
29+
3. The tool updates the scaffold and preserves customizations, allowing the user to review and apply the changes.
30+
31+
In both cases, if conflicts cannot be resolved automatically, developers can manually address
32+
them before completing the update.
33+
34+
## Open Questions
35+
36+
1. Do we need to create branches to perform the three-way merge, or can we use local temporary directories?
37+
38+
> While temporary directories are sufficient for simple three-way merges, branches are better suited for
39+
> complex scenarios. They provide history tracking, support collaboration, integrate with CI/CD workflows,
40+
> and offer more advanced conflict resolution through Git’s merge command. For these reasons, it seems more
41+
> appropriate the usage of branches to ensure flexibility and maintainability in the merging process.
42+
43+
2. What Git configuration options can facilitate the three-way merge?
44+
45+
Several Git configuration options can improve the three-way merge process:
46+
47+
```bash
48+
# Show all three versions (base, current, and updated) during conflicts
49+
git config --global merge.conflictStyle diff3
50+
51+
# Enable "reuse recorded resolution" to remember and reuse previous conflict resolutions
52+
git config --global rerere.enabled true
53+
54+
# Increase the rename detection limit to better handle renamed or moved files
55+
git config --global merge.renameLimit 999999
56+
57+
# Set up custom merge drivers for specific file types (e.g., YAML or JSON)
58+
git config --global merge.<driver>.name "Custom Merge Driver"
59+
```
60+
61+
These configurations enhance the merging process by improving conflict visibility,
62+
reusing resolutions, and providing better file handling, making three-way merges
63+
more efficient and developer-friendly.
64+
65+
3. If we change Git configurations, can we isolate these changes to avoid affecting the local developer environment when
66+
the tool runs locally?
67+
68+
It seems that changes can be made using the `-c` flag, which applies the configuration only
69+
for the duration of a specific Git command. This ensures that the local developer
70+
environment remains unaffected.
71+
72+
For example:
73+
74+
```bash
75+
git -c merge.conflictStyle=diff3 -c rerere.enabled=true merge
76+
```
77+
78+
4. How can we minimize and resolve conflicts effectively during merges?
79+
80+
- **Enable Git Features:**
81+
- Use `git config --global rerere.enabled true` to reuse previous conflict resolutions.
82+
- Configure custom merge drivers for specific file types (e.g., `git config --global merge.<driver>.name "Custom Merge Driver"`).
83+
84+
- **Encourage Standardization:**
85+
- Adopt a standardized scaffold layout to minimize divergence and reduce conflicts.
86+
87+
- **Apply Frequent Updates:**
88+
- Regularly update projects to avoid significant drift between the scaffold and customizations.
89+
90+
These strategies help minimize conflicts and simplify their resolution during merges.
91+
92+
## Summary
93+
94+
### Workflow Example:
95+
96+
1. A developer creates a project with Kubebuilder `v4.4`.
97+
2. The tooling uses the release of Kubebuilder `v4.5`.
98+
3. The tool:
99+
- Regenerates the original base source code for `v4.4` using the `clientVersion` in the `PROJECT` file.
100+
- Generates the base source code for `v4.5`
101+
4. A three-way merge integrates the changes into the developer’s project while retaining custom code.
102+
5. The changes now can be packaged into a pull request, summarizing updates and conflicts for the developer’s review.
103+
104+
### Steps:
105+
106+
The proposed implementation involves the following steps:
107+
108+
1. **Version Tracking**:
109+
- Record the `clientVersion` (initial Kubebuilder version) in the `PROJECT` file.
110+
- Use this version as a baseline for updates.
111+
112+
2. **Scaffold Generation**:
113+
- Generate the original scaffold using the stored version.
114+
- Regenerate the scaffold with the latest Kubebuilder release.
115+
116+
3. **Three-Way Merge**:
117+
- Ensure git is configured to handle three-way merges.
118+
- Merge the original scaffold, updated scaffold, and the user’s customized project.
119+
- Preserve custom code during the merge.
120+
121+
4. **(For Actions) - Pull Request Creation**:
122+
- Open a pull request summarizing changes, including details on conflict resolution.
123+
- Schedule updates weekly or provide an on-demand option.
124+
125+
#### Example Workflow
126+
127+
The following example code illustrates the proposed idea but has not been evaluated.
128+
This is an early, incomplete draft intended to demonstrate the approach and basic concept.
129+
130+
We may want to develop a dedicated command-line tool, such as `kubebuilder alpha update`,
131+
to handle tasks like downloading binaries, merging, and updating the scaffold. In this approach,
132+
the GitHub Action would simply invoke this tool to manage the update process and open the
133+
Pull Request, rather than performing each step directly within the Action itself.
134+
135+
```yaml
136+
137+
name: Update Kubebuilder Scaffold
138+
139+
on:
140+
workflow_dispatch:
141+
schedule:
142+
- cron: '0 0 * * 0' # Run weekly to check for new Kubebuilder versions
143+
144+
jobs:
145+
update-scaffold:
146+
runs-on: ubuntu-latest
147+
148+
steps:
149+
- name: Check out the repository
150+
uses: actions/checkout@v2
151+
with:
152+
fetch-depth: 0 # Ensures the full history is checked out
153+
154+
- name: Set up environment and dependencies
155+
run: |
156+
sudo apt-get update
157+
sudo apt-get install -y jq curl
158+
159+
- name: Read Kubebuilder version from PROJECT file
160+
id: read_version
161+
run: |
162+
export INITIAL_VERSION=$(grep "clientVersion" PROJECT | awk '{print $2}')
163+
echo "::set-output name=initial_version::$INITIAL_VERSION"
164+
165+
- name: Download and install the initial Kubebuilder version
166+
run: |
167+
curl -L https://github.com/kubernetes-sigs/kubebuilder/releases/download/${{ steps.read_version.outputs.initial_version }}/kubebuilder_${{ steps.read_version.outputs.initial_version }}_linux_amd64.tar.gz -o kubebuilder_initial.tar.gz
168+
tar -zxvf kubebuilder_initial.tar.gz
169+
sudo mv kubebuilder /usr/local/kubebuilder_initial
170+
171+
- name: Generate initial scaffold in `scaffold_initial` directory
172+
run: |
173+
mkdir scaffold_initial
174+
cp -r . scaffold_initial/
175+
cd scaffold_initial
176+
/usr/local/kubebuilder_initial/bin/kubebuilder init
177+
cd ..
178+
179+
- name: Check for the latest Kubebuilder release
180+
id: get_latest_version
181+
run: |
182+
export LATEST_VERSION=$(curl -s https://api.github.com/repos/kubernetes-sigs/kubebuilder/releases/latest | jq -r .tag_name)
183+
echo "::set-output name=latest_version::$LATEST_VERSION"
184+
185+
- name: Download and install the latest Kubebuilder version
186+
run: |
187+
curl -L https://github.com/kubernetes-sigs/kubebuilder/releases/download/${{ steps.get_latest_version.outputs.latest_version }}/kubebuilder_${{ steps.get_latest_version.outputs.latest_version }}_linux_amd64.tar.gz -o kubebuilder_latest.tar.gz
188+
tar -zxvf kubebuilder_latest.tar.gz
189+
sudo mv kubebuilder /usr/local/kubebuilder_latest
190+
191+
- name: Generate updated scaffold in `scaffold_updated` directory
192+
run: |
193+
mkdir scaffold_updated
194+
cp -r . scaffold_updated/
195+
cd scaffold_updated
196+
/usr/local/kubebuilder_latest/bin/kubebuilder init
197+
cd ..
198+
199+
- name: Copy current project into `scaffold_current` directory
200+
run: |
201+
mkdir scaffold_current
202+
cp -r . scaffold_current/
203+
204+
- name: Perform three-way merge with scaffolds
205+
run: |
206+
# Create a temporary directory to hold the final merged version
207+
mkdir merged_scaffold
208+
# Run three-way merge using scaffold_initial, scaffold_current, and scaffold_updated
209+
# Adjusting merge strategy and paths to use directories
210+
diff3 -m scaffold_current scaffold_initial scaffold_updated > merged_scaffold/merged_files
211+
212+
- name: Copy merged files back to main directory
213+
run: |
214+
cp -r merged_scaffold/* .
215+
git add .
216+
git commit -m "Three-way merge with Kubebuilder updates and custom code"
217+
218+
- name: Create Pull Request
219+
uses: peter-evans/create-pull-request@v3
220+
with:
221+
commit-message: "Update scaffold to Kubebuilder ${{ steps.get_latest_version.outputs.latest_version }}"
222+
title: "Update scaffold to Kubebuilder ${{ steps.get_latest_version.outputs.latest_version }}"
223+
body: |
224+
This pull request updates the scaffold with the latest Kubebuilder version ${{ steps.get_latest_version.outputs.latest_version }}.
225+
branch: kubebuilder-update-${{ steps.get_latest_version.outputs.latest_version }}
226+
```
227+
228+
## Motivation
229+
230+
A significant challenge faced by Kubebuilder users is keeping their projects up-to-date with the latest
231+
scaffolds while preserving customizations. The manual processes required for updates are time-consuming,
232+
error-prone, and often discourage users from adopting new versions, leading to outdated and insecure projects.
233+
234+
The primary motivation for this proposal is to simplify and automate the process of maintaining Kubebuilder
235+
projects. By providing a streamlined workflow for updates, this solution ensures that users can keep
236+
their projects aligned with modern standards while retaining their customizations.
237+
238+
### Goals
239+
240+
- **Automate Updates:** Detect and apply scaffold updates while preserving customizations.
241+
- **Simplify Updates:** Generate pull requests for easy review and merging.
242+
- **Provide Local Tooling:** Allow updates locally with preserved customizations.
243+
- **Keep Projects Current:** Ensure alignment with the latest scaffold improvements.
244+
- **Minimize Disruptions:** Enable scheduled or on-demand updates.
245+
246+
### Non-Goals
247+
248+
- Resolving complex conflicts in customizations.
249+
- Automatically merging updates without review.
250+
251+
## Proposal
252+
253+
### User Stories
254+
255+
- **As a Kubebuilder maintainer**, I want to help users keep their projects updated with minimal effort, ensuring they adhere to best practices and maintain alignment with project standards.
256+
- **As a user of Kubebuilder**, I want my project to stay up-to-date with the latest scaffold best practices while preserving customizations.
257+
- **As a user of Kubebuilder**, I want an easy way to apply updates across multiple repositories, saving time on manual updates.
258+
- **As a user of Kubebuilder**, I want to ensure my codebases remain secure and maintainable without excessive manual effort.
259+
260+
### Implementation Details/Notes/Constraints
261+
262+
N/A
263+
264+
### Risks and Mitigations
265+
266+
- **Risk**: Potential conflicts with heavily customized code.
267+
- *Mitigation*: GitHub as other tools provide a preview mode where users can inspect conflicts before the merge is attempted.
268+
269+
### Proof of Concept
270+
271+
The feasibility of re-scaffolding projects has been demonstrated by the `kubebuilder alpha generate` command.
272+
273+
**Command Example:**
274+
275+
```bash
276+
kubebuilder alpha generate
277+
```
278+
279+
For more details, refer to the [Alpha Generate Documentation](https://kubebuilder.io/reference/rescaffold).
280+
281+
This command allows users to manually re-scaffold a project, to allow users add their code on top.
282+
It confirms the technical capability of regenerating and updating scaffolds effectively.
283+
284+
This proposal builds upon this foundation by automating the process. The proposed tool would extend this functionality
285+
to automatically update projects with new scaffold versions, preserving customizations.
286+
287+
The three-way merge approach is a common strategy for integrating changes from multiple sources.
288+
It is widely used in version control systems to combine changes from a common ancestor with two sets of modifications.
289+
In the context of this proposal, the three-way merge would combine the original scaffold, the updated scaffold, and the user’s custom code
290+
seems to be very promising.
291+
292+
## Drawbacks
293+
294+
- **Frequent Conflicts:** Automated updates may often result in conflicts, making the process cumbersome for users.
295+
- **Complex Resolutions:** If conflicts are hard to review and resolve, users may find the solution impractical.
296+
- **Maintenance Overhead:** The implementation could become too complex for maintainers to develop and support effectively.
297+
298+
## Alternatives
299+
300+
- **Manual Update Workflow**: Continue with manual updates where users regenerate
301+
and merge changes independently, though this is time-consuming and error-prone.
302+
- **Use alpha generate command**: Continue with updates partial automated provided
303+
by the alpha generate command.
304+
- **Dependabot Integration**: Leverage Dependabot for dependency updates, though this
305+
doesn’t fully support scaffold updates and could lead to incomplete upgrades.

0 commit comments

Comments
 (0)