It's cost me hundreds to thousands of dollars to implement nontrivial workflows because of how the YAML is parsed (for example, empty strings when using a secret that has been renamed or removed) and the lack of introspection or debuggability when something goes wrong.
It's gotten to the point where new any new workflows I write are thin wrappers around a single script and I don't import any actions besides actions/checkout (even that has been bug prone, historically).
All that said, it's not like other platforms are better. But they certainly are cheaper and don't have dumb breakages when you need cross platform builds (has upload-artifact been fixed for executables on MacOS yet?)
A good exercise is to look at a simple but nontrivial build/test/release automation:
- on pull requests build & test, on tags build/test and release, and once a day release a nightly build.
- cache dependencies globally and build artifacts on each branch for incremental builds
- once daily, clear out artifacts on deleted branches or merged PRs
A script to do this would be around 100 lines and be readable/maintainable (if build/test or release change, it is shared by the different cases!). The script can have a main entrypoint that will dispatch to the runners as needed.
I know it sounds a lot like jenkins, but node has a much better ecosystem than groovy.