Refs #324. Fixes the failure on the first real run of cleanup-actions.
What the error was
write EPROTO ... ssl3_get_record:wrong version number
That reads like a TLS misconfiguration and sends you looking at certificates and protocol versions. It is neither. The server answered in cleartext, and OpenSSL tried to parse that as a TLS record.
Why
scripts/cleanup-workflow-runs.js required node's https module and always used it, defaulting to port 443:
That was fine while GITEA_HOST was typed by hand as a public https:// URL. It stopped being fine the moment the workflow started supplying it from github.server_url, which inside the runner is the address act_runner reaches Gitea on rather than the public one — plain HTTP on a container port here.
So the script sent a TLS handshake to a plaintext port. The scheme in the URL was being ignored entirely.
The fix
Honour the scheme, and let the default port follow from it. A URL naming neither http nor https is refused up front with a message naming the value, because this script speaks nothing else and a bad input is worth reporting as one.
The endpoint is also printed before the first request rather than after one succeeds. That is what made this cost more than it should have: the failure named a symptom inside OpenSSL and said nothing about where the script had been pointed.
endpoint : http://127.0.0.1:58123
repository : bermudalamb/redefined-designs
total runs : 1
Testing
Run end to end against a plaintext HTTP stub: listing, age selection and the dry-run report all work over http. A bad scheme exits 1 with a message naming the value it was given.
Worth running with apply left at false once this is merged, to confirm the endpoint line and the counts look right before deleting anything.
Refs #324. Fixes the failure on the first real run of `cleanup-actions`.
## What the error was
```
write EPROTO ... ssl3_get_record:wrong version number
```
That reads like a TLS misconfiguration and sends you looking at certificates and protocol versions. It is neither. The server answered in **cleartext**, and OpenSSL tried to parse that as a TLS record.
## Why
`scripts/cleanup-workflow-runs.js` required node's `https` module and always used it, defaulting to port 443:
```js
const req = https.request({ hostname: origin.hostname, port: origin.port || 443, ... })
```
That was fine while `GITEA_HOST` was typed by hand as a public `https://` URL. It stopped being fine the moment the workflow started supplying it from `github.server_url`, which inside the runner is the address `act_runner` reaches Gitea on rather than the public one — plain HTTP on a container port here.
So the script sent a TLS handshake to a plaintext port. The scheme in the URL was being ignored entirely.
## The fix
Honour the scheme, and let the default port follow from it. A URL naming neither `http` nor `https` is refused up front with a message naming the value, because this script speaks nothing else and a bad input is worth reporting as one.
The endpoint is also printed **before** the first request rather than after one succeeds. That is what made this cost more than it should have: the failure named a symptom inside OpenSSL and said nothing about where the script had been pointed.
```
endpoint : http://127.0.0.1:58123
repository : bermudalamb/redefined-designs
total runs : 1
```
## Testing
Run end to end against a plaintext HTTP stub: listing, age selection and the dry-run report all work over `http`. A bad scheme exits 1 with a message naming the value it was given.
Worth running with `apply` left at `false` once this is merged, to confirm the endpoint line and the counts look right before deleting anything.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The workflow failed on its first real run with:
write EPROTO ... ssl3_get_record:wrong version number
which reads like a TLS misconfiguration and sends you looking at certificates and protocol versions. It is neither. The server answered in cleartext and OpenSSL tried to parse that as a TLS record.
The script required node's https module and always used it, defaulting to port 443. That was fine while the host was typed by hand, and it stopped being fine the moment the workflow started supplying it from github.server_url. Inside the runner that is the address act_runner reaches Gitea on, not the public one, and here it is plain HTTP on a container port.
So the scheme in GITEA_HOST is honoured rather than assumed, and the default port follows from it. A URL naming neither http nor https is refused up front, because this script speaks nothing else and reporting that as a bad input beats failing later inside a request.
The endpoint is now printed before the first request rather than after one succeeds. That is the part that made this cost more than it should have: a transport failure said nothing about where it had been pointed, so the message named a symptom in OpenSSL and nothing about the run at all.
Verified against a plaintext HTTP stub end to end: the listing, the age selection and the dry-run report all work over http, and a bad scheme exits 1 with a message naming the value it was given.
Refs #324
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Refs #324. Fixes the failure on the first real run of
cleanup-actions.What the error was
That reads like a TLS misconfiguration and sends you looking at certificates and protocol versions. It is neither. The server answered in cleartext, and OpenSSL tried to parse that as a TLS record.
Why
scripts/cleanup-workflow-runs.jsrequired node'shttpsmodule and always used it, defaulting to port 443:That was fine while
GITEA_HOSTwas typed by hand as a publichttps://URL. It stopped being fine the moment the workflow started supplying it fromgithub.server_url, which inside the runner is the addressact_runnerreaches Gitea on rather than the public one — plain HTTP on a container port here.So the script sent a TLS handshake to a plaintext port. The scheme in the URL was being ignored entirely.
The fix
Honour the scheme, and let the default port follow from it. A URL naming neither
httpnorhttpsis refused up front with a message naming the value, because this script speaks nothing else and a bad input is worth reporting as one.The endpoint is also printed before the first request rather than after one succeeds. That is what made this cost more than it should have: the failure named a symptom inside OpenSSL and said nothing about where the script had been pointed.
Testing
Run end to end against a plaintext HTTP stub: listing, age selection and the dry-run report all work over
http. A bad scheme exits 1 with a message naming the value it was given.Worth running with
applyleft atfalseonce this is merged, to confirm the endpoint line and the counts look right before deleting anything.🤖 Generated with Claude Code
The workflow failed on its first real run with: write EPROTO ... ssl3_get_record:wrong version number which reads like a TLS misconfiguration and sends you looking at certificates and protocol versions. It is neither. The server answered in cleartext and OpenSSL tried to parse that as a TLS record. The script required node's https module and always used it, defaulting to port 443. That was fine while the host was typed by hand, and it stopped being fine the moment the workflow started supplying it from github.server_url. Inside the runner that is the address act_runner reaches Gitea on, not the public one, and here it is plain HTTP on a container port. So the scheme in GITEA_HOST is honoured rather than assumed, and the default port follows from it. A URL naming neither http nor https is refused up front, because this script speaks nothing else and reporting that as a bad input beats failing later inside a request. The endpoint is now printed before the first request rather than after one succeeds. That is the part that made this cost more than it should have: a transport failure said nothing about where it had been pointed, so the message named a symptom in OpenSSL and nothing about the run at all. Verified against a plaintext HTTP stub end to end: the listing, the age selection and the dry-run report all work over http, and a bad scheme exits 1 with a message naming the value it was given. Refs #324 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>