A little earlier I was simply browsing some of the repositories I've been adding and got very slow load times, and then a 500.
As I've said elsewhere: I really wouldn't expect perfection. I doubt that Codeberg has the money behind it that GitHub does. But, again, there is that issue with moving off GitHub because of instability; from that point of view it would feel like swapping some occasional instability for what, at the moment, is feeling like regular instability to the point that I wouldn't get too much done.
I've had a GitLab account since December 2017. This came about because of the new job I started in January 2018. They used a self-hosted internal instance of GitLab for all their code, so it made sense I get familiar with it (it wasn't hard; especially back in 2017 it was near enough a clone of GitHub in terms of what it did). Since then, though, I've never really done anything with it. I think I had a repo or two on there for a short while, but I must have nuked them at some point because the account has been empty for the longest time.
A Codeberg account, on the other hand, only got created the other day. Having created this, I got to thinking about how I might use it. In doing so I thought back to my GitLab account and then also got to thinking about where all my public code lives, and how "safe" it is.
Now, sure, the whole point of Git is that it's distributed. Forges are a useful thing to have and work with, but they shouldn't be the place where your code lives. On the other hand, I've had so many machines, and so many work environments, that it has become the case that my GitHub account has become the storage location for my code and projects.
Mostly this is fine. If GitHub were to disappear tomorrow I imagine we'd all have bigger things to be worrying about anyway. But the principle stands: why not distribute the load? Why not distribute the effort when it comes to sharing code I write?
So yesterday I finally decided on a plan: for the moment at least, I'm going to keep using GitHub as my "primary" location for working on stuff. It's where I'll have WiP branches, it's where I'll keep issues, it's where I'll encourage people to raise requests and stuff, it's where I'll host this blog. But I'm going to start syncing projects to both GitLab and Codeberg. I see this as having two benefits: anyone who doesn't want to interact with GitHub can now easily fork code, and if they wish they can raise issues and the like too. Meanwhile, in doing this, I'll also have the added benefit of my code being "backed up" in at least three different locations1.
#!/bin/sh# Check if a repository name was providedif[-z"$1"];thenecho"Error: No repository name provided."echo"Usage: $0 <repo-name>"exit1fiREPO_NAME="$1"# Check if the current directory is a Git repositoryif!gitrev-parse--is-inside-work-tree>/dev/null2>&1;thenecho"Error: This directory is not a Git repository."exit1fiecho"Configuring multi-forge backup sync for: $REPO_NAME"# Set up the remote called backups. Anchor it to Codeberg.
gitremoteremovebackups>/dev/null2>&1
gitremoteaddbackups"ssh://git@codeberg.org/davep/${REPO_NAME}.git"# Set up the push URLs.
gitremoteset-url--pushbackups"ssh://git@codeberg.org/davep/${REPO_NAME}.git"
gitremoteset-url--add--pushbackups"git@gitlab.com:davep/${REPO_NAME}.git"# Only ever backup main.
gitconfigremote.backups.pushrefs/heads/main:refs/heads/main
echo"----------------------------------------------------"echo"Backups configured:"
gitremote-v
echo"----------------------------------------------------"echo"To perform the initial sync, run: git push backups main"### setup-forge-sync ends here
I'm going to keep all repo names the same2. So when I use this script it'll set things up so I can git push backups and main will then get pushed up to both GitLab and Codeberg. I don't feel the need to be keeping any WiP branches in sync or kicking about, likewise any gh-pages branches.
While I'm sure I could have done something a little more automated, this feels like a neat and simple approach, and also allows me to curate what appears in the two other places over time (I suppose, eventually, I'll mirror everything that isn't a dead experimental repo, but meanwhile I'll prioritise projects that are either still very useful or which I'm actively developing and maintaining).
Yes, I have other backups too, but they're always current-working-machine type backups. ↩
Except, perhaps, for any repo whose name starts with .; I seem to recall that GitLab can't handle that, for some bizarre reason. Perhaps that's fixed now? ↩
I'm out and about, MacBook Air in tow, with a couple of hours to kill. So I dip into a coffee shop and decide to tinker with stuff. I open up Codeberg and...
I was delighted to find my preferred user name was actually available, which made me more inclined to create an account. The account creation process itself seemed a bit of a faff. I can't remember the details now, but it took a couple of goes and necessitated a password reset and recovery to actually get in (I recall there was some sort of error when I tried to use the activation link sent in the email, which took quite a while to turn up, but the rest is hazy, and I wasn't taking notes). It might be that it didn't help that I was signing up in a mobile browser.
That aside, though, I got up and going in the end.
At this point I'm not quite sure what I want to do with the account. While I'm nowhere near being willing or able to move my GitHub activity over there, it at least feels like it might be a viable backup location via which I can make code available. Also, and probably more importantly, it makes it easier for me to follow projects that use it as their primary (or only) forge.
This morning I found myself following a link to a project hosted there. It looked interesting, it looked like something I'd want to follow. It didn't go so well. I hit the star button and... busy circle.
This lasted for a while with nothing happening. So I refreshed the page, no star on the repo, so I tried again. Same result. I tried a third time and got something different right away.
At some point I ended up with a big fat 500 page.
Do I see this as an issue? Of course not. Could be I caught it on a bad day. Stuff happens. I've seen a 500 from things I'm responsible for before now. I'm not going to expect perfection. But it does remind me that leaping from one forge to another, to chase platform stability, and in doing so give up a long history, is a risky endeavour without a guaranteed payoff.
While I'm messing around in the background of BlogMore, looking at the state of the code and looking for opportunities to clean it up, either by hand, or by pitting agent against agent, I've also been doing the odd little fix here and there.
I've just released BlogMore v2.19.0, which has a couple of fixes, and also a small improvement.
The first fix is something I noticed late on last week when I was sharing one of the archive pages from my blog with someone. I noticed that the preview that appeared didn't have the default blog image, nor did it have any sort of description. This should happen in that, on any page that isn't a post with a specific cover image or description, it should fall back to the blog's defaults. Turns out this logic was missing from things like the date-based archives, the category and tag archives, and a number of other parts of the generated output.
The second fix is to the recently-added backlinks feature. While reviewing the effect of something else I was working on, I specifically noticed that this post didn't have a backlink section at the bottom, despite the fact that it was linked to from this post. The cause seemed pretty clear: the fact that I had parentheses in the URL. My guess was that the regex that the link-finding code uses wasn't taking this sort of thing into account; my guess was right.
The final change in this release is that the per-build cache-busting feature has been extended to all the JavaScript files that are generated when building the site. Before it was mostly only applied to the main stylesheets and a couple of long-standing bits of JavaScript. Now it's added to the code that's used for search, the code-block support code, the graph, etc. This means that if there are any changes in those files between builds and deployments of a site, there's less chance of unexpected behaviour that needs a "clear the cache first" fix.
It seems that dunking on GitHub is the flavour of the day. At the moment most of the social/news type things I tend to read are filled with the Ghostty news, as well as a small revival of posts and links to blog posts about all the recent outages. It's understandable. It does seem that something has shifted with GitHub in the last few months. While it hasn't been the site I used to enjoy for quite some time now, it just seems to be getting worse at the moment.
As I read all of this I find myself mostly nodding along. For the most part I'm not finding that GitHub is getting in the way and stopping me from doing the things I want to do, and for the most part it does act as a vital tool that lets me get work done, and also lets me enjoy my longest-enjoyed hobby. On the other hand I couldn't help but sigh and think "yeah, I get why this is the time that people are done" when I opened up the PR page for this blog, just now, and saw this:
It does get me thinking about my relationship with GitHub, and how long I've been using it. As I've written before, I created my account back in 2008; I was within the first 30,000 users. While my use of it was only very occasional for quite a long time, for the last decade I've been constantly interacting with it. It is somewhere I visit constantly, not just to do work on my own projects, but to read what other people are doing. One of the first things I do every morning, when I sit down at my desk, is open my GitHub dashboard page and have a scroll through the feed to see what people I follow have been up to.
It's generally been the most fulfilling feed I've read.
But I'm also getting that feeling I got when I hung on to my Twitter account far longer than I really should have; not just because of the general vibe of "it's falling apart", but also other types of questionable behaviour. The degrading performance, the troubling business relationships, the over-emphasis on all things AI... it adds up.
There is a sense that some time ago was the time to move elsewhere as my sociable forge (probably around the time that Microsoft took over), and that not having done that, now is the second best time. But the effort of making that move is non-trivial and, quite frankly, I'd want to see where folk start to land, if they started to move away in any numbers at all. For me the real utility of GitHub isn't the "it's somewhere to store my shit" thing, it's the socially coding thing.
Then there's the follow-up problem: if some other forge was to become the next flavour of the decade, it too would probably end up suffering the same fate as GitHub.
Perhaps now is the time for me to start looking into options for collaborative code forges that offer the same sort of solution that Mastodon does for Twitter-like nattering.
After releasing the graph view yesterday I got to thinking that it might be nice if the "tooltips" for the nodes in the graph were a little richer. Since we already know how many posts are within a category, or have a specific tag, it makes sense that those counts should be shown; posts themselves have descriptions available and some even have cover images that could be turned into thumbnails. Why not make use of all of that?
So I've made use of all of that. As mentioned, categories and tags simply show the count of posts related to them:
Posts will show the title, date, description and the cover image if available:
I'll admit that the transparency is a little distracting -- this comes from the library being used for the graph -- but I kind of like it. I'm going to roll with it now and see how I feel about it as time goes on. It's not like I expect a reader to read the post in the tooltip, it's an invitation to click through and read the actual post.
Another small change is something I've been meaning to address for a while. While BlogMore supports a modified time for a post it never shows it or uses it in any meaningful way. So now I've updated the way the time of a post is displayed so that, if there is a modified time, it's also shown:
The final change came in as a request over on Mastodon. The wish being that there was an easy method, that didn't require the user spin out their own copy of a template just to do it, of changing the title of the backlinks section on a post from "References & Mentions" to something else. That seemed fair so I've introduced backlinks_title.
I did some more tinkering with BlogMore yesterday, adding two new features. The first is one I've been considering adding for a wee while now.
For a large part of the lifetime of this blog I used Disqus to provide a comments section on every post. It was, as you'd imagine for a small personal blog, a pretty quiet thing; I'd get the odd comment from time to time but it wasn't significant. This worked well for the longest time, until Disqus decided that they were going to force adverts into your pages if you were using the free tier. Now, I'm fine with paying for tools I use, but I wasn't using Disqus enough to make the cost worth it. I'm also not opposed to a bit of subtle advertising to help cover costs either.
What Disqus did wasn't subtle. It was far from subtle. It was a horror show of the worst kind of sleazy advertising you can imagine.
So I removed it and called it a day on comments.
After the work on BlogMore was well under way I did start thinking about this problem again. Given how BlogMore is constructed, anyone using it could override a template and include whatever they want; with this in mind I looked at static-site-friendly comment options but nothing really stood out. Every solution seemed to either heavily rely on a third party service (see above for possible problems), self-hosting such a service (spinning up hosts and web servers and databases and stuff is the antithesis of using a static site generator to get stuff done easily), or some hacky use of a social media platform or other discussion venue that would require the reader jump through hoops that really looks like "go away, I don't want to hear from you".
So I concluded that it just wasn't worth the effort and I've done nothing with it.
Meanwhile: on occasion I have had people just email me about a post. Good old email, like in the good old days of the Internet. I kind of liked that. In fact I really liked that. So over the weekend, after receiving just such an email the other day, I decided I'd add a feature to BlogMore that provided just that: an invitation to send an email at the end of every post.
The configuration file now has two new properties that support this. The first is invite_comments. This is a boolean value that simply turns on or off the feature. The second is invite_comments_to. This should be set to an email address that the reader will be invited to direct their comment or question or whatever.
I've made the latter a little smart, in that it's actually a template, so that you can control the email address used per-post. This could be great for filtering, etc. Examples could be:
blog-comment@example.com
blog-comment-{year}{month}{day}@example.com
{author}+comment@example.com
And so on. You get the idea.
Further to this there's also post frontmatter properties of the same name. In this case the frontmatter setting always overrides the configuration file setting, for that single post. Also the invite_comments_to frontmatter setting isn't a template -- it's being set for a single post so that didn't seem necessary. The point of the frontmatter is it gives the flexibility to turn the invite off for an individual post (or indeed turn it on if the global setting is for it to be off).
The effect of all of this is that, if the invitation setting is on and if there is an email address available, this little box will appear at the bottom of a post:
When the reader clicks on the link it should open their MUA of choice and pre-fill the to address, and should also pre-fill the subject with the title of the post they're emailing from.
At some point in the future it might be interesting to take this even further and produce a map of interconnected posts; for now though I think this is enough.
Apparently "some time in the future" was the following day; because that also got added while I was hacking on the sofa. There's a new --with-graph command line option, and with_graph configuration file setting, that adds a Graph page to the top "menu" of the blog. The result looks something like this:
Given the nature of the graph and that the viewer is naturally going to want to explore, it can be toggled into a "full screen" (well, "mostly most of the page") mode too:
The graph itself (built using force-graph) can be explored in the ways you'd reasonably expect, allowing zooming, panning around, dragging nodes around to get a better view of things, and so on.
If you click on any of the nodes the graph will show you everything that's linked to it:
and if you click the node again it will take you to the post, tag archive or category archive, depending on what it is you are clicking on.
So far I'm finding this is working really well as yet another method of discovering posts and themes, etc; it's already helped me find some "under-used" tags that deserved to be added to posts to better connect things. I suspect the feature will need refining over time, especially from a cosmetic point of view, but the result feels very usable as it stands.
BlogMore has had a new release, bumping the version to v2.16.0. There are two main changes in this update, both coming from a single idea: internal back-links.
Where it makes sense, I always try and link posts in this blog to other related posts, but I've never really had a sense of how interconnected things are. So, the first new thing I added was a with_backlinks configuration option. This is off by default, but when turned on, will add a list of any referring posts to the bottom of a post.
Like some of the work I did in the stats page, this feels like another interesting method of discovering posts and related subjects within a blog.
Once this work was done, it seemed to make sense to use the link-gathering code to then get a sense of which posts are most often linked to within a blog, and so a table of most-linked posts has been added to the stats page.
This particular table will only appear in the stats if with_backlinks is set to true.
At some point in the future it might be interesting to take this even further and produce a map of interconnected posts; for now though I think this is enough.
I've just made a small update to BlogMore. This fixes a minor cosmetic issue that's been bugging me for a while, but one that I kept forgetting to address. I noticed it again on a recent post. The issue is that if there are enough tags on a post that the collection of tags runs to a second line, there was no space between those lines.
Now, as of v2.15.0, there's a little bit of breathing room between those lines.