Previously the cache would become stale. Now the same incremental
cache mechanism in use for the QL cache is adopted (and factored out
in a separate action).
Namely, pushes on main will populate the cache using the commit hash as
key, while PRs will try to use the cache of their merge base, read-only.
To avoid the cache growing out of control, a simple cache eviction is
done on pushes.
This is a developer QoL improvement, where running codegen will skip
writing (and especially formatting) any files that were not changed.
**Why?** While code generation in itself was pretty much instant, QL
formatting of generated code was starting to take a long time. This made
unconditionally running codegen quite annoying, for example before each
test run as part of an IDE workflow or as part of the pre-commit hook.
**How?** This was not completely straightforward as we could not work
with the contents of the file prior to code generation as that was
already post-processed by the QL formatting, so we had no chance of
comparing the output of template rendering with that. We therefore store
the hashes of the files _prior_ to QL formatting in a checked-in file
(`swift/ql/.generated.list`). We can therefore load those hashes at
the beginning of code generation, use them to compare the template
rendering output and update them in this special registry file.
**What else?** We also extend this mechanism to detect accidental
modification of generated files in a more robust way. Before this patch,
we were doing it with a rough regexp based heuristic. Now, we just store
the hashes of the files _after_ QL formatting in the same checked file,
so we can check that and stop generation if a generated file was
modified, or a stub was modified without removing the `// generated`
header.
* A unique workflow file has been created merging all `swift-*.yml`
workflows
* Change filtering at job level was added using [dorny/paths-filter][1]
* only one build of the extractor is made, and then shared via cache
(not as an artifact because of [this longstading issue][2])
* integration tests are now run on on macOS
* qltests are not run any more on macOS to cut on feedback time
* autobuilder tests were moved to the macOS build step to avoid loading
bazel twice
[1]: https://github.com/dorny/paths-filter#examples
[2]: https://github.com/actions/upload-artifact/issues/38