Quickly delete all packages from GitHub registry using a blob
Script to remove GitHub registry images Hey, though I quickly just share a script to get rid of packages you don’t want anymore from your GitHub registry. #!/bin/bash set -e # Variables OWNER=$1 # Replace with your GitHub username or organization name PACKAGE_GLOB=$2 # Glob pattern for package names passed as an argument (e.g., "package*" to match all) # makes sure that important packages are not removed by accident contains() { found=1 array=(place-very-important-packages-here-to-make-sure-they-are-not-deleted) for v in "${array[@]}" do if [[ "$1" == "$v" ]]; then echo "$v found not deleting" found=0 break fi done } # Function to delete a package version delete_package_version() { contains "$1" # echo "found: $found" if [[ $found -eq 1 ]]; then name=${1//\//%2F} echo "deleting package with name: $name" gh api -X DELETE "/user/packages/container/$name" --silent fi } # Fetch the list of all available packages for the user/organization echo "Fetching packages matching the glob pattern '$PACKAGE_GLOB'..." # Fetch all package names and filter with globbing # Change `/users/` to `organization` if you are looking at organization packages. ALL_PACKAGES=$(gh api "/users/$OWNER/packages?package_type=container" --jq '.[].name' --paginate) MATCHED_PACKAGES=$(echo "$ALL_PACKAGES" | grep "$PACKAGE_GLOB") if [[ -z "$MATCHED_PACKAGES" ]]; then echo "No packages found matching the pattern '$PACKAGE_GLOB'." exit 1 fi # echo "Deleting the following packages: ${MATCHED_PACKAGES}" # Loop through matched packages and delete them SAVEIFS=$IFS # Save current IFS (Internal Field Separator) IFS=$'\n' # Change IFS to newline char packages=($MATCHED_PACKAGES) # split the `names` string into an array by the same name IFS=$SAVEIFS # Restore original IFS for (( i=0; i<${#packages[@]}; i++ )) do delete_package_version "${packages[$i]}" done echo "All matching packages deleted!" That is all. ...
Test Post - Please ignore
Hello This is just a test post to see if I did my hugo build correctly.
How I track tasks with Obsidian
How I track tasks with Obsidian Hello. This will be a run-down on how I track tasks and projects and long-term things, like reading a book, tracking a project or traveling using the PARA method. Let’s get to it! Task tracking queue The way I track tasks is through a queuing system. To not get overloaded by tasks, I just simply put the next task into the queue and take out the top recent if I’m done. Unless something really urgent comes along I don’t disrupt this flow. Meaning, once I have a task out and #active that’s the task I’m going to be working on! ...
Update your CRDs with confidence
Update your CRDs with confidence Hello. I would like to write about a release for crd-to-sample-yaml1. It’s the release version v0.8.02. This version brings with it a feature to test the validity of your CRD changes. It means that if you change your CRD it will test if the changes do not break working samples of that version. This is achieved by a helm unittest type of YAML based test scenarios and snapshot generation. ...
Using cert-manager as a subchart for your own Helm Chart
Using cert-manager as a subchart Hello. In today’s post, I would like to show how to set up cert-manager as a subchart. Not only that, but also, how to add a Job to make sure that cert-manager is installed and its webhook is up and running so it can process any Issuers that are going to be applied with your own chart. Let’s get to it. Defining a subchart To define a subchart, simply add it as a dependency in your Charts.yaml like this: ...
Discoverable functional options pattern
Hello. Today’s will be a quick post. Everyone knows and loves/hates functional options1 in Go. The biggest gripe people get with it is, that the options aren’t discoverable and that there is no IDE support for nicely auto-completing options. My thought about this was that, what if we would just hang it on a struct? Let’s see how that looks. Consider this normal server builder with options: type Server struct { Name string Address string Port int } func WithName(name string) ServerOptFn { return func(s *Server) { s.Name = name } } func WithAddress(address string) ServerOptFn { return func(s *Server) { s.Address = address } } func WithPort(port int) ServerOptFn { return func(s *Server) { s.Port = port } } type ServerOptFn func(*Server) func NewServer(opts ...ServerOptFn) *Server { s := &Server{} for _, o := range opts { o(s) } return s } Now, what if you would like to retain the niceness of the clean options pattern where you don’t have to specify and empty struct but still could use a struct to gather the options together? ...
Journey from Testing into Software Development
Hello, Dear Reader! Settle in for a long one this time. I would like to write about my journey from being a Tester back in 2004 to being a software engineer today ( 2024 ). A mere 20 year long journey. I’m going to write down how I got this far, what it took, the sacrifices, fears, doubts and all the things in between. Let’s get started. The early days Around 2002, I became a student for a two year long certificate study for a position called Software Programmer. It was a paid course. My mother paid for the two years, it was the cheapest options at that time in Hungary. The school, SZAMALK, was 80km from where I lived, so I had to travel everyday. The bus ride took about 1.5 hours that I mostly managed to sleep through. Then school until 2pm-ish and then travel back home. Another 1.5 hours. I woke up at 5AM to get to school on time. It was quite rough. I mostly slept through my classes. ...
crd-to-yaml now supports HTML as an output format
Hello! Just wanted to give an update to my crd-to-sample-yaml tool. It, now, supports creating a standalone HTML output. Why, you may ask? Well, now you can host the generated content as a static page on your website. That’s pretty handy. Here is a sample output: Go and get it while it’s hot in version v0.4.0. That’s all. Thanks for reading!
Generic dig for map key using typed parameters
Generic dig for map key using typed parameters Hello! I was fiddling with a way of getting out values from a map that is of format map[string]any. But I wanted my type safety as well. This was coming from digging out keys from a Metadata field. The metadata was in a JSON format. This is what I came up with: / FetchValueFromMetadata fetches a key from a metadata if it exists. It will recursively look in // embedded values as well. Must be a unique key, otherwise it will just return the first // occurrence. func FetchValueFromMetadata[T any](key string, data *apiextensionsv1.JSON, def T) (t T, _ error) { if data == nil { return def, nil } m := map[string]any{} if err := json.Unmarshal(data.Raw, &m); err != nil { return t, fmt.Errorf("failed to parse JSON raw data: %w", err) } v, err := dig[T](key, m) if err != nil { if errors.Is(err, errKeyNotFound) { return def, nil } } return v, nil } func dig[T any](key string, data map[string]any) (t T, _ error) { if v, ok := data[key]; ok { c, k := v.(T) if !k { return t, fmt.Errorf("failed to convert value to the desired type; was: %T", v) } return c, nil } for _, v := range data { if ty, ok := v.(map[string]any); ok { return dig[T](key, ty) } } return t, errKeyNotFound } The interesting part is the dig method and the type assert to the desired part. Calling this with something like: ...
CRD to YAML as WASM website
CRD to YAML as WASM website A while ago, I wrote about Generating Sample YAML files from CRDs. It’s a tool I created that lives here. It has a front-end service as well for convenience. I wrote it in a traditional client-server manner. It’s running from a Docker Swarm container. But, as I was thinking about it, nothing in this service requires interaction with a server. It gets some user input, processes it, and has some output. I could have written it in plain Javascript. But, since I don’t know JavaScript, or don’t know it well enough, and I do know GO, and I wanted to become more familiar with WASM, this was the perfect learning opportunity. ...