Local Cluster for Personal Projects

I’ve been trying to figure out a simple way to have a CI/CD pipeline for my personal projects. I’ve tried several options but was never happy with anything. The last attempt is to use a local microk8s cluster with production ready configuration and certificate management so I can easily deploy any project to the cluster without much work. This is the setup I ended up with.

There are 3 main pieces to this: Github actions, a docker registry and the kubernetes cluster itself.

On a home server I’m running a docker registry only accessible through the local network and also a github actions runner.

On the same server I’m running a single node microk8s cluster with the following addons:

Read More

Slack Interaction Routing using Django resolvers

Developing a integration for Slack is not easy task. Slack’s API is pretty great and allows a lot of freedom. But when you start adding buttons, integrations and, more recently, interactions with blocks your code will quickly become a never-ending list of if/the/else clauses.

While developing integrations the new slack interactions we were writing were becoming unmangeable. For every new button there would be a new if block_id == "feedback-button" so new solutions needed to be found.

The best one was using Django’s routing mechanism to treat the interactions as urls on a website. Once this mindset was introduced everything became much easier. Let’s start with some examples. First the main methods that make this possible:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def slack_resolver(url: str) -> ResolverMatch:
for urlconf in settings.SLACK_URLCONFS:
# try the various urlconf files we have
try:
resolver = resolve(url, urlconf=urlconf)
return resolver
except Resolver404:
continue
raise Resolver404()

def slack_reverse(viewname, args=None, kwargs=None):
for urlconf in settings.SLACK_URLCONFS:
try:
return reverse(viewname, urlconf=urlconf, args=args, kwargs=kwargs)
except NoReverseMatch:
continue
raise NoReverseMatch(f"Reverse for {viewname} not found: args: {args}, kwargs: {kwargs}")

As the method signatures show the slack_resolver method receives the current url being processed and return the resolver to call the view’s function.

Read More

Astral Chain

I’ve been postponing playing this game for a long time. Being a father of a 2 year old and having my own company doesn’t allow a lot of time for JRPG’s. But I couldn’t resist much more. I love the style of this game. And honestly it touches on everything I love on JRPG’s, demon-like robots (Legions), great story (a bit convoluted, but I love those), fresh mechanics that make fighting super fun and quirky characters that give life to the world that was created.

Image from https://astralchain.fandom.com/wiki/Axe_Legion

As far as JPRG’s go this one changed the formula a bit because you have levels (chapters). Progress is done by missions and not a free flowing experience like normal JPRG’s (like Final Fantasies). I liked this approach a lot because it focuses your time and doesn’t make you grind and spend endless hours just to get somewhere.

Definitely a game to go on the excelent experiences list.

Read More