The job-level env used runner.tool_cache, which isn't available until a
runner is assigned, so the workflow failed to parse. Set it on the
setup-dotnet step, where the runner context is valid.
setup-dotnet defaulted to /usr/share/dotnet, which the runner user cannot
write to (Permission denied). Point DOTNET_INSTALL_DIR at runner.tool_cache
so the 8.0 SDK installs into a writable, cached location.