Every GitHub release lookup in the Ansible roles is anonymous -- 14 files hit api.github.com and a search for Authorization across ansible/ returns nothing. That is fine on a laptop and expensive anywhere the address is shared.
The anonymous limit is 60 requests an hour PER IP, and all HyperI on-prem infrastructure leaves through one public address. So an image build, a converge and CI all draw on the same 60, and a single run selecting infrastructure plus a couple of languages spends a good fraction of it by itself -- k8s.yml, cloud.yml, data_tools.yml, ghostty.yml, colima.yml, go.yml, the rust setup script.
It killed our desktop template build at task 90 with x_ratelimit_remaining: '0' and x_ratelimit_used: '60'. An earlier run the same morning got to task 280, so it is not deterministic -- it depends on what else in the estate has been talking to GitHub in the preceding hour.
Two things make it worse than the raw number suggests:
- The diagnosis is buried. The
uri module dumps the 403 response headers rather than saying "rate limited", and the shell call sites that do curl ... | grep tag_name end up with an empty version and fail later on a 404 or a tar error that names nothing.
- Anonymous quota is consumed by whoever gets there first, so the run that fails is rarely the run that spent it.
What would fix it for us: read a token from the environment (GITHUB_TOKEN or GH_TOKEN) and set the Authorization header when one is present, staying anonymous when it is not. Then an unattended build can pass one and a laptop run is unchanged.
DONE WHEN an image build can make its release lookups without competing for anonymous quota.
Every GitHub release lookup in the Ansible roles is anonymous -- 14 files hit
api.github.comand a search forAuthorizationacrossansible/returns nothing. That is fine on a laptop and expensive anywhere the address is shared.The anonymous limit is 60 requests an hour PER IP, and all HyperI on-prem infrastructure leaves through one public address. So an image build, a converge and CI all draw on the same 60, and a single run selecting
infrastructureplus a couple of languages spends a good fraction of it by itself -- k8s.yml, cloud.yml, data_tools.yml, ghostty.yml, colima.yml, go.yml, the rust setup script.It killed our desktop template build at task 90 with
x_ratelimit_remaining: '0'andx_ratelimit_used: '60'. An earlier run the same morning got to task 280, so it is not deterministic -- it depends on what else in the estate has been talking to GitHub in the preceding hour.Two things make it worse than the raw number suggests:
urimodule dumps the 403 response headers rather than saying "rate limited", and the shell call sites that docurl ... | grep tag_nameend up with an empty version and fail later on a 404 or a tar error that names nothing.What would fix it for us: read a token from the environment (
GITHUB_TOKENorGH_TOKEN) and set the Authorization header when one is present, staying anonymous when it is not. Then an unattended build can pass one and a laptop run is unchanged.DONE WHEN an image build can make its release lookups without competing for anonymous quota.