Tom Almeida

Tom Almeida's website

Rescheduling when I do blog posts

It's been almost a full week since my last blog post, and I should probably discuss why.

When I originally restarted this blog, I intended to write one blog post per day. Barely three weeks later and it seems like I've given up all hope of trying for that trend.

I found, not long after I started, that when I wrote about things that I'd given some thought to, I wrote a lot more words than I thought I would. Unfortunately, I am limited by my ability to type fast and get my words onto my computer. This often means that even if I have a fully-formed and planned out idea, it can easily take me 45 minutes to an hour to write.

I'm almost the entire way through my Masters, and the semester truly has gotten back into the swing of things. I have mid-semester tests coming up, and assignment are beginning to become due. In addition, my thesis will soon need to be submitted, which means that for me, my time is at a premium.

As such, I'm instead going to move to writing one blog post a week, starting next week on Sunday. I think this should give me the time to be able to spend on my other assignments and allow me to properly spend the time on these posts.

I should probably say that this one blog post a week isn't due to a lack of ideas - I almost have more ideas written down than I have taken days off writing! Unfortunately, I just need to put more time into my university work for the moment.

Permalink

My ideal computer at the moment

Chris Siebenmann recently wrote about how is ideal machine isn't in an existing category. Interestingly, I find myself in the same sort of situation, however with an almost entirely different conclusion.

As I have previously mentioned, I am of the opinion that as the number of machines you try to do work on increases, the ease of synchronization between those machines increases exponentially. This means that for me, an ideal machine would be easily portable so that it can be used anywhere with minimal effort to transport. This effectively pushes me into a being left with the options of either a laptop (as in an ultrabook) or a tablet.

Tablets are in an interesting position right now where they are continuously increasing in power and ability, but still lack many of the features that I'd require in a daily driver machine, namely the ability to easily compile code locally, easy access to the terminal and a keyboard-driven UI (tiling window managers truly have gotten the better of me). Thus, I am left with the sole choice of a laptop.

Now the nitpicking starts, what sort of specs do I want in a laptop? Well, as you may have picked up from my rant about why esports will never be mainstream, I play CS:GO on a regular basis, and also enjoy casually playing a number of other single-player games such as BioShock and Civilization. As such, I would quite like to be able to continue playing these games as I use them as my primary source of leisure.

Say what you will about their power, but gaming laptops are both (generally speaking) incredibly heavy and immobile, and very difficult to upgrade. I have no intention of needing to update my laptop every 1-2 years just so I can upgrade my GPU. So for me, the option that makes the most sense is a laptop with an external GPU enclosure, so the GPU can be upgraded independently of the rest of the machine. This would also allow me to dock my machine when I get home and be able to get use out of the high refresh rate monitors that I own - something that would be extremely valuable for gaming. External GPU enclosures do exist on the market (although they are not widely used), however they are almost all based on Thunderbolt 3. This leads me to my next problem.

I'd much rather use an AMD-based than an Intel-based CPU, as the current generation of Ryzen-based laptop CPUs run circles around their Intel equivalents. With the addition of their extra cores, both compiling and gaming would be significantly better on an AMD-based laptop than Intel-based laptop. This comes with the issue of USB 4 (the equivalent Thunderbolt 3 standard which can be used for external GPU enclosures) only being supported on the next-generation of AMD chips.

Thus my ideal machine doesn't yet exist, but I fully expect that in a year or two it might.

Permalink

Turns out you can get in contact with me

Today's update will be a fair bit shorter than my usual fair (thank goodness!).

I mentioned in this post that there would be no way to contact me easily for feedback and comments. My belief at the time of writing was that if I wanted to receive emails from an email address related to this domain (e.g. something@tommoa.me), I'd have to purchase a domain email service.

It turns out, I'm wrong about that. I've been able to setup tom@tommoa.me to send me email, but unfortunately there's been no way (as far as I can tell) for me to be able to send mail back using that address unless I pay for email. From my hosting provider, it only costs about $2 AUD per month for email (compared to GSuite at $8.50 AUD per month), but I don't want to waste even $2 if it turns out that the email address isn't going to be used.

If I start getting enough email through the address above that it becomes worth it to me to buy purchase the domain, I will, but as my current audience (as far as I'm aware) is a grand total of zero people, it's definitely not worth my money right now.

Permalink

Automatically updating git submodules using GitHub Actions

I know that the mono-repository is in style at the moment, but git submodules are a fantastic (and probably over complicated) tool for being able to store components of a git repository that may need to be kept used, but separate. For example, you may need to track a specific upstream version of another repository that isn't controlled by you or your organization for use in your repository, or you might want to mix repository visibility or share some code between different repositories that need to be separated.

I personally use submodules in the repositories for a wide variety of uses. For example, my research project uses a submodule to track the latest version of the codebase that I am modifying so I can write patches to match against those versions. Another example is my site, which has a bunch of submodules to track various things which get published there, from my resume and my research project, to the theme that I use for both my site and this blog.

I only recently moved to using the same codebase for the theme of my site and blog, which has both made my life easier and caused me a great deal of heartache - and almost all of the heartache came from git submodules. You see, submodules are tied to a specific commit, and running a command like git submodule update (which you'd think updates a submodule to the latest version) only checks out the submodule to the same commit as what your local repository already has stored. This makes life a little more difficult - how can I easily update submodules without having to specifically know the remotes, branches or location of all of my submodules?

First, all of the submodules have their remotes and locations (and optionally branches) stored in the .gitmodules file, which can be used to iterate through the submodules and pull down the latest versions. Another option is using the git submodule foreach command to update the submodules by fetching the remotes and then checking out latest commit, which has the disadvantage submodules not (by default) being checked out branches, and instead is checked out to commits. Both of these options are obviously not particularly ergonomic to work with, and so git introduced the --remote flag to git submodule update to tell it to update to the branch tracked on the remote instead of the local repository.

Great, so now we know update our submodules to the latest remote commit (huzzah!), but I want to push to one repository and watch the other repositories automatically update to track that commit (instead of requiring me to run a command). How can we do that?

GitHub Actions to the rescue! (although unfortunately it won't quite get us all the way there)

GitHub Actions allows you to trigger commands on arbitrary events using the repository_dispatch event. The first step is to create a GitHub Action in our repository that updates submodules for us.

Of course, the simplest way to do this would simply be to recursively clone the repository using GitHub's checkout action, to run git submodule update --remote and then git push the changes back into the repository. Unfortunately, this doesn't quite work out for two reasons; we won't have write access to the repository and we won't be able to clone private repositories. We can get around this by passing a personal access token to GitHub's checkout action and telling it that we need to pull submodules recursively. An example of this action can be found below, and is actually what I use in my site's repo.

name: Update module
on:
  repository_dispatch:
    types: update
jobs:
  update:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.PAT }}
          submodules: recursive
      - name: Update module
        run: |
          git submodule update --init --recursive --checkout -f --remote -- "${{github.event.client_payload.module}}"
          git config --global user.name "GitHub Action"
          git config --global user.email "noreply@github.com"
          git commit -am "deploy: ${{github.event.client_payload.module}} - ${{github.event.client_payload.sha}}"
          git push

The second step is to create the trigger for the repository_dispatch in the submodule repositories themselves. This can be done using the excellent repository-dispatch action to send the event. An example of this can be shown below.

name: Dispatch to repo
on: [push, workflow_dispatch]
jobs:
  dispatch:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        repo: ["owner/repo"]
    steps:
      - name: Push to repo
        uses: peter-evans/repository-dispatch@v1
        with:
          token: ${{ secrets.PAT }}
          repository: ${{ matrix.repo }}
          event-type: update
          client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}", "module": "owner/submodule", "branch": "master"}'

This of course works with submodules that you control, but what about for submodules that you don't control? Unfortunately there's no way to start an action based on a push in a different repository, nor is there a way to create a webhook that you could use to trigger another action from a repository that you don't control. As such you are left with two options; to simply run the update action at a frequent interval or to hack together a way to do it with activity email notification and a repository_dispatch. I know which of the two I'd rather implement in a hurry!

Permalink

On the enjoyment of work

I'm of the opinion that in society, the general attitude towards jobs is that you should "do something that you're passionate about". If medicine takes your fancy, then take up your stethoscope and get to it. Does the thought of court put you in a tizzy? Find a briefcase and start practicing law. Is graphic design your passion (yes)? Then grab your wacom tablet and get ready to draw.

This is an attitude that gets taught to kids and is especially pushed throughout high school as teenagers get closer to the end of the secondary education and begin thinking about their adult life. I remember being told to "picture what I want to be doing in thirty years" and to start taking steps towards doing that when I leave high school. For me, I this was not exactly great advice - I had no clue what I wanted to pick between music or computer science! Whilst I eventually decided on doing computer science, I definitely understand the reason why there's so many people doing music, arts or history degrees - its what they've been told to do! And if there was a high demand for professions in those areas, they would be able to spend their lives doing a job that they loved. Unfortunately, given the number of people taking the courses and the general lack of capital-creating potential, its unrealistic that all of them would be able to get gainful employment, especially as the expected age of retirement seems to increase. I don't think that this is necessarily a point against doing the arts as a degree (again, I almost picked music, and my brother is actually studying French Horn), but I think that the wish to be entirely fulfilled by your full-time employment is both dangerous and misinformed.

I've heard of engineering processes being like a four-sided piston several times - you need to have a balancing act between quality, cost, time and scope, and as each of them is moved, the others also need to be readjusted. I think life is much the same way, there's things that need balancing and we can't have them all going at full steam. I can't be all in on my work and spending massive amounts of overtime whilst also trying to manage a family, stay in touch with older friends and keep a hobby. It's entirely unrealistic.

Most workplaces recognise this (or are forced to in Australia by the government) and have a maximum set of hours that you are paid to work - everything else is overtime. So long as you aren't taking an enormous amount of time to commute to work and aren't continuing to work past your hours, that leaves roughly a third (or a quarter when factoring in eating) of the weekday - plus the weekend - to spend on things which aren't work - family, friends and hobbies. All of those are great things with which to be fulfilled.

My maternal Grandfather spent working years as a clinical biochemist. He has long since retired and his "hobby" is now his employment; gardening. He's become so proficient at caring for plants and identifying native flora that he's become an invaluable member of several parks in helping with botanical management. Whilst I know that he enjoyed his time as a clinical biochemist, it was not his "be all and end all" to the point where it was where he gained his fulfilment from, instead he got fulfilment from his family, friends and hobbies.

This is much of the same approach that I've taken to music. My gainful employment will be coming from software development, something that, yes, I enjoy, but that doesn't mean that I'll stop playing music. Over the course of my time at university, I've continued my involvement in music, and by my own estimation am a significantly better musician now than I was then. Whilst I am certain that the total improvement is likely not as great as if I had formally studied music, having music as a hobby that I enjoy and can gain fulfilment from without relying on it for my finances is both freeing and adds to my enjoyment of it.

I think that this is the right balance of things. Even in jobs in which you would be theoretically fulfilled, you can still have things go wrong. Sudden deadlines, a difficult workmate or an overbearing boss can all make jobs significantly less enjoyable. If your previously fulfilling work is no longer enjoyable, then what are you enjoying?

Thus my charge to you is this; don't put all your eggs in one basket. In the end, work is work and should be approached as such. It is a means to an end, to give you an opportunity to live the other parts of your life and shouldn't be what your entire life is about. So take up a hobby, spend more time with your family and friends, or start a job that you know you won't enjoy but can use to further one of them. I'd bet it'd make life more rewarding.

(disclaimer: author is an university student who hasn't ever had to apply this advice in practice and is writing at about 1AM. Take it with ten grains of salt)

Permalink