For small Go projects, it's easy to tell yourself that gofmt, go mod tidy, and golangci-lint are habits, not policy. That usually works right up until a pull request fails because generated files changed, go.sum drifted, or a formatter was only run on one laptop.
The pattern I keep coming back to is simple: define the validation contract once, usually in a Makefile or Taskfile.yml, then let pre-commit provide fast local feedback and GitHub Actions enforce the same expectations for everyone else. Local hooks keep the loop short. CI keeps the rules shared, visible, and hard to accidentally bypass.
This isn't the only way to validate a Go repository, and it isn't always necessary. But for Go projects with generated code, multiple contributors, or public pull requests, it's a very practical baseline.
Dependency updates are easy to picture one repo at a time. They get political fast when the count is hundreds or thousands: security response, CI minutes, reviewer attention, repo standards, and how much supply-chain theater your org is willing to run.
Most organizations and users will start with Dependabot on GitHub. It's an obvious choice: first-party, no extra service to stand up. Plenty of teams still reach for Renovate when policy, monorepos, or odd manifests stop fitting Dependabot's mold.
Blunt matrix:
Capability
Dependabot
Renovate
GitHub integration
First-party, tight dependency graph and advisory wiring
Strong GitHub support, but you run it as an app, Action, or your own worker
Configuration model
Simple repository-local YAML
Layered policy model with presets and package rules
Custom dependency extraction
Limited to supported ecosystems
Strong, especially with custom regex managers
Monorepo handling
Good for straightforward layouts
Better for large, mixed, policy-heavy monorepos
Pull request grouping
Useful but bounded
Very granular by manager, package, path, dependency type, and update type
Automerge policy
Usually implemented with GitHub Actions and branch protection
First-class Renovate policy, still gated by GitHub rules
Security updates
Best native GitHub Advisory Database integration
More programmable, but integration depends on deployment model
Most terminal emulators ask you to make peace with an awkward tradeoff. You can have something fast but austere, polished but slow, powerful but painfully non-native. Ghostty, created by Mitchell Hashimoto, is interesting because it doesn't merely try to improve one side of that triangle. It tries to make the tradeoff smaller. The result is a terminal that is GPU-accelerated, deeply configurable, standards-aware, and designed to feel like a first-class citizen on the platform it runs on.
At the highest level, Ghostty is a modern terminal emulator for macOS and Linux. That sounds ordinary right up until you look at how it positions itself. The project is explicitly built around three goals:
Fast
Feature-rich
Native
The third goal is where the project gets interesting.
There are plenty of fast terminals. There are plenty of featureful terminals. There are also terminals that feel at home on a specific operating system. Very few try to be genuinely strong in all three categories at once, because that is much harder than slapping a fast renderer on a cross-platform UI toolkit and calling it a day.
Ghostty takes the harder path. On macOS, it uses real Apple frameworks. On Linux, it integrates with GTK4 and the surrounding desktop environment. Underneath those platform-specific shells is a shared Zig core that handles terminal emulation, rendering, and the heavy lifting that makes Ghostty feel so absurdly responsive.
If you spend a good chunk of your day in a shell, an editor, a multiplexer, or a remote session, that combination matters more than it may seem on paper.
Issues and pull requests accumulate quickly on any active project. Without structure, a repository becomes a flat list of work with no clear sense of what belongs together, what's blocking a release, or how close you're to shipping. Milestones give that structure: lightweight containers that define the payload of a release, track progress automatically, and surface what remains without requiring a separate project board or external tool.
This post covers how milestones work, how to name and manage them, how to operate them through the UI, the GitHub CLI, and the REST API, and how to automate the tedious parts with GitHub Actions. It's opinionated: these are the practices that work in production open source repositories, not a neutral survey of every option.
A milestone is a named container attached to a repository. It holds issues and pull requests, carries an optional description and due date, and displays a live progress bar computed from the ratio of closed to total items. Nothing more. That simplicity is the point.
Most developers first encounter JetBrains code inspections as red underlines and yellow warnings inside the editor. That live feedback is the same inspection engine behind Problems, batch runs, and shared profiles, even when the UI says "problem" in places. It's useful, but it isn't the real power move. Instead, learn how to run a deliberate inspection pass across a file, package, module, or whole project before you commit your changes and open a pull request.
That workflow lives in Problems, Project Errors, Code | Inspect Code, scope selection, and inspection profiles. Once you start using this, PyCharm and GoLand stop being fancy editors and become a code quality gate.
Applies Across JetBrains IDEs
My focus here is on PyCharm and GoLand because they're the tools I use most. The same inspection model also shows up across other JetBrains IDEs, though the exact inspection groups, plugins, and file-type support will vary by product and project setup.
By the time a problem reaches CI/CD, you've already paid the context-switch tax:
You wrote the code.
You staged it.
You pushed it.
You waited for the pipeline.
You reopened the work.
By contrast, when PyCharm or GoLand finds the issue locally, you can usually fix it while the code is still fresh in your head.
That's the value of leaning on inspections end to end. The IDE isn't only marking mistakes in the current file as you type. It can also run structured inspection passes against broader scopes of code and show you the results in one place, grouped, triaged, and ready to fix.
For a lot of Python and Go developers, that second part is the missing piece.
It also does something more subtle over time: It teaches you patterns.
If you keep paying attention to the same warnings, quick fixes, and inspection results, you start to internalize better habits before the IDE has to remind you.
If you already use GitHub security features for Go, it is tempting to assume CodeQL and Dependabot cover everything you need. They do not fully replace govulncheck.
For Go projects, govulncheck adds a very useful layer: it understands the Go vulnerability database and uses package and call graph information to reduce noise. That means it can help answer a more practical question than "is this module version mentioned in an advisory?" It can help answer "does this vulnerability affect code my project actually uses?"
That is enough of a difference that I think govulncheck is worth surfacing directly in GitHub code scanning, not just running as an isolated terminal command or a one-off CI step.
make is still one of the most useful tools in a developer's toolbox, but a lot of modern repositories need something more portable, more readable, and easier to share between local development and CI. Task is a fast, cross-platform task runner that keeps the good part of a Makefile, one command for common project workflows, while replacing the rough edges with a YAML-based Taskfile.yml, built-in dependency orchestration, variables, templating, caching, and first-class behavior on Windows, macOS, and Linux.
If you're using securitySpec to deploy VMware Cloud Foundation 9.x with external CA-signed ESX certificates, the bring-up can look successful while still leaving you with one surprise:
Post Deployment Configuration Drift
The first ESX host will be deployed with a VMCA-signed certificate instead of the external CA-signed certificate provided.
I ran into this while testing external CA-signed certificates through both the API and Ansible. The JSON payload was accepted, the instance bring-up completed, the ESX hosts retained their external CA-signed certificates except for first ESX host, the one used during the bootstrap for the vCenter appliance.
Before you begin the upgrade, review the following checklist.
Back up anything you care about.
If the system is a VM, take a snapshot.
Make sure the current 24.04 LTS install is fully patched.
Make sure you have enough free disk space.
Be prepared to answer interactive prompts during the upgrade.
On Ubuntu Server, I would also review any third-party repositories or PPAs before you start. They are a common source of upgrade friction, and Ubuntu may disable them during the release upgrade anyway.