Skip to content

archive: add gitea generic package registry backend - #705

Open
mahaase wants to merge 9 commits into
BobBuildTool:masterfrom
mahaase:feature/gitea-artifact-backend
Open

archive: add gitea generic package registry backend#705
mahaase wants to merge 9 commits into
BobBuildTool:masterfrom
mahaase:feature/gitea-artifact-backend

Conversation

@mahaase

@mahaase mahaase commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Add a gitea archive backend that stores binary artifacts in a Gitea generic package registry. The backend is configured with the server url, the registry owner and the generic package name. Credentials are given explicitly as a token (personal access token) or a user/password pair for HTTP basic authentication, so uploads work even inside the build sandbox. Optional sslVerify and retries keys tune the transport.

Uploads perform a preflight check and report clearer connection and authentication errors.

  • archive: implement the gitea backend with upload preflight and clearer connection/auth error reporting
  • input: validate the gitea archive backend configuration
  • doc: document the gitea archive backend
  • test: cover the gitea archive backend

depends on #706 (archive: do not leak URL credentials in user visible messages)

@codecov

codecov Bot commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.28%. Comparing base (7b00892) to head (abade2f).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #705      +/-   ##
==========================================
+ Coverage   89.23%   89.28%   +0.04%     
==========================================
  Files          50       50              
  Lines       16450    16512      +62     
==========================================
+ Hits        14679    14742      +63     
+ Misses       1771     1770       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mahaase

mahaase commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

i'm not sure, but the root cause of the failed windows build could be:
Error: Failed to download: [Errno 28] Disk full

@mahaase
mahaase force-pushed the feature/gitea-artifact-backend branch from f72e3d7 to fe1828f Compare July 31, 2026 12:44
@jkloetzke

Copy link
Copy Markdown
Member

Thanks. I'll have a look after my vacation...

@jkloetzke jkloetzke left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you split the change into multiple commits? At least one for the implementation, one for the documentation and one for the tests? Also, if you need to extend the Webdav class, that should be a separate commit as well.

Comment thread doc/manual/configuration.rst Outdated
Comment thread pym/bob/archive.py Outdated
Comment thread pym/bob/archive.py Outdated
Comment thread pym/bob/archive.py Outdated
@mahaase
mahaase force-pushed the feature/gitea-artifact-backend branch from fe1828f to d54543d Compare August 19, 2026 06:41
@mahaase

mahaase commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

@jkloetzke Thanks for your review and feedback!

Hopefully everything should be addressed. The change is now split into four commits:

  1. webdav: support conflict replies and deleting by path — the WebDav
    extensions, isolated as requested
  2. archive: add gitea generic package registry backend — the implementation
  3. doc: document the gitea archive backend
  4. test: cover the gitea archive backend

@mahaase
mahaase force-pushed the feature/gitea-artifact-backend branch from 183fe76 to 49a591d Compare August 19, 2026 07:16
@mahaase

mahaase commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

disk full issue again.

The HTTP basic authentication credentials are part of the archive URL. All
three places that turn that URL back into a string for display used the raw
netloc, which still carries the "user:password@" part:

  * getArchiveName() feeds _namedErrorString(), so the credentials were
    printed on *every* error message -- including the perfectly ordinary
    "artifact not found" that occurs for each package on a cache miss. No
    verbosity flag needed.
  * _remoteName() is the "details" of the DOWNLOAD/UPLOAD/MAP-SRC/CACHE-BID/
    CACHE-FPR/MAP-FPRNT status lines, shown with -v.
  * getArchiveUri() is printed by "bob archive".

These messages routinely end up in build logs and CI consoles.

WebDav._getURL() already stripped the credentials before putting the URL on
the wire, so this only ever affected the display strings. Factor that logic
out into stripUserInfo() and use it in the three spots above as well.

While at it, cut at the last '@' instead of the first. urlparse() delimits
the user info at the last '@', so for a password containing an unencoded '@'
the previous split('@')[1] produced a bogus host -- and revealed part of the
password on top.

The optional 'name' archive setting was no workaround: _remoteName() and
getArchiveUri() do not consult it.
The http backend takes the basic authentication credentials as part of the
URL. State that they are not echoed back in the status lines, so it is clear
that putting them there does not put them into every build log.
testNoCredentialsInMessages checks the three user visible strings derived
from the archive URL: the password and the '@' delimiter must be gone while
the host must survive. Reverting archive.py alone makes all three subtests
fail.

TestStripUserInfo covers the helper itself: URL without credentials (returned
unchanged), plain removal, a password containing an unencoded '@', an IPv6
literal host, and preservation of the urlsplit() result type.
The SSL context was created in the constructor. That rendered the object
unpicklable, though, and the archive backends are sent to the up-/download
executor processes. Using the http backend with "sslVerify: False" therefore
aborted the build with a "cannot pickle 'SSLContext' object" error. Create
the context on demand instead.

Additionally two small extensions are needed for package registries that
are not real WebDAV servers:

Some servers do not honour the "If-None-Match" header but refuse to
overwrite an existing file with a 409 instead. Treat that like the 412
that a WebDAV server would send.

Add deletePath() that takes an absolute path like upload() and
download() do. The existing delete() keeps its relative filename and
just delegates.
Add a `gitea` archive backend that stores binary artifacts in a Gitea
generic package registry. The backend is configured with the server
`url`, the registry `owner` and the generic `package` name. Artifacts
are put below `{url}/api/packages/{owner}/generic/{package}/` with one
package version per artifact.

As for the http backend the HTTP basic authentication credentials are
part of the URL. Gitea accepts a personal access token in place of the
password. The registry only speaks plain HTTP (HEAD, GET, PUT and
DELETE), so the WebDav class does the transport.

The managed operations (scan/clean) are not implemented because they
would require the Gitea package list API.

While at it, move the retry loop of the http backend into a small
function that both backends share.
Add a mock of the Gitea generic package registry that translates the
package API layout to the on-disk layout of the shared archive tests, so
that all common upload/download assertions apply unchanged. On top of
that, cover authentication via the URL and the individual error replies
of the registry.
GiteaArchive has its own getArchiveName(), _remoteName() and getArchiveUri().
Built on the raw netloc they would carry the "user:password@" part into the
status lines and error messages, most notably into the perfectly ordinary
"artifact not found" that occurs for every package on a cache miss.

Use the same stripUserInfo() helper as the http backend.
TestGiteaAuthArchive already runs against a mock registry that requires basic
authentication, so the credentials are readily at hand. Assert that the three
user visible strings derived from the URL carry neither the token nor the
user name, while the host survives.

Reverting the previous commit makes all three subtests fail.
@mahaase
mahaase force-pushed the feature/gitea-artifact-backend branch from 49a591d to abade2f Compare August 19, 2026 09:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants