I’ve noticed this phenomenon few times already, and I think there’s nothing worse than having a 30-60s feedback loop. The one that keeps you glued to the screen but otherwise is completely nonproductive.
I tried for many moons to replicate GHA environment on local and it’s impossible in my context. So every change is like „push, wait for GH to pickup, act on some stupid typo or inconsistency, rinse, repeat”.
It’s like a slot machine „just one more time and it will run”, eating away focus and time.
It took me 25 minutes to get 5s build process. Naive build with GHA? 3 minutes, because dependencies et al. Ok, let’s add caching. 10 hours fly by.
The cost of failure and focus drop is enormous.
I wish GitLab/GitHub would provide a way to do this by default, though.
mise supports an experimental bootstrapping feature: it can download itself and install the tools required for the project.
See https://mise.jdx.dev/cli/generate/bootstrap.html and https://mise.jdx.dev/continuous-integration.html#bootstrappi...
Me and my colleagues have had numerous issues setting up pre-commit because it inherits Python's atrocious infrastructure.
I'm curious how this is going to deal with actually running plugins? Will it take the same approach as pre-commit and add dedicated not-very-good support for a load of different languages?
[tools]
uv = 'latest'
[tasks.python_uv_task]
run = """
#!/usr/bin/env -S uv run --script
# /// script
# dependencies = ["requests<3", "rich"]
# ///
import requests
# your code here
"""I use Asdf to manage versions of all programs in a monorepo. Works great (well, actually asdf's UX is terrible, but it works reliably, and the plugin design is great).
For development, I don't ever load environment variables into my current shell session. I run a script or Makefile which loads any necessary variables, does a thing, and then exits. It would be a nightmare to have to constantly check if my current shell session had X variable in it.
I use Make for repeatable small commands that will vary per directory, or for simple parallelizing or ordered execution of commands. I have a big one that handles Helm installs, and a few more for Terraform, Packer, asdf, etc. I also use them for deployments in hierarchical environment directories, where environment variables are loaded from parent directories. I love that Make has all the features it has, because I always find myself eventually reaching for something you don't find in "just a task runner", and it makes my life easier.
I use shell scripts when I need to make a composeable tool that'll be slightly longer or more complicated than a Make target should be. I have saved so much time and effort writing these tools in shell rather than Python or something, where there is inevitably way more bugs and dependencies. The only time I have needed to use something more complex than shell is when I have a lot of APIs to deal with that also deal in JSON; if it's a lot of complexity it's better than curl/jq, but if it's only one small task, curl/jq is better.
The end result works great. The whole environment just needs asdf installed (from Homebrew, for example). With stock Make and the stock Bash v3, I can manage everything automatically, everything's version-pinned and automated, all variables get loaded at runtime as needed, and the whole thing can be grokked by just reading some simple Makefiles.
The only thing I want to fix now is to get rid of the superfluous Makefiles from directories (they're all symlinked back to one Makefile). It's a pain to re-symlink them all when I change directory structure. Probably should just write a script for it...
It's better at managing tools than `asdf`, very close to `direnv` and superior to `make` as a task runner (more verbose but much easier to understand). One of the advantages is that `mise` tasks can be standalone files (you can even write file tasks in python if you prefer, see https://mise.jdx.dev/tasks/file-tasks.html)
IMO, mise tasks are much better than `just`. A few things that make mise superior:
— solid environment variables support
— can run tasks in parallel, has a watch task feature, support for skipping tasks,…
— mise supports file tasks (i.e., running shell scripts, as many comments are suggesting here - https://mise.jdx.dev/tasks/file-tasks.html)
— mise tasks are defined using `toml`, and not a custom syntax