feat: accept deploy reports from the deployment pipeline - #112
Open
turegjorup wants to merge 4 commits into
Open
turegjorup wants to merge 4 commits into
turegjorup wants to merge 4 commits into
Conversation
addInstallation() was called only when the tag row was created, and it is the only thing that sets Installation::gitTag. A redeployment, or the same release on a second server, therefore left the installation pointing at its previous tag or at nothing - which also dropped it out of the repo advisory rollups, since those inner join GitRepo through gitTags to installations.
Sites deployed from a prebuilt artifact carry no .git directory, so the server harvester cannot detect their origin and tag and they show up here with neither - and with no GitRepo row, which is why the economics sync keeps reporting repositories it cannot link. The deployment is the only party that knows, so it now reports to POST /api/deploy_results. Installations record whether they are a git working copy or a release artifact, which both tells the two apart in the admin and stops the harvester's empty git result from clearing a tag only the deployment can know. Clearing it would not merely unlink the tag: RemovedRelationsListener deletes a git tag, and its repository, as soon as no installation points at it. The pipeline authenticates with a key from the environment rather than the database, so rotating it touches no data and can move to the vault later. The key grants ROLE_DEPLOYER and nothing else.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #112 +/- ##
=============================================
+ Coverage 40.32% 45.00% +4.68%
- Complexity 1132 1174 +42
=============================================
Files 150 156 +6
Lines 3576 3704 +128
=============================================
+ Hits 1442 1667 +225
+ Misses 2134 2037 -97
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
API Specification - Non-breaking changesAPI Changelog 1.0.0 vs. 1.0.0API ChangesPOST /api/deploy_results
|
1 similar comment
API Specification - Non-breaking changesAPI Changelog 1.0.0 vs. 1.0.0API ChangesPOST /api/deploy_results
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Link to ticket
https://leantime.itkdev.dk/#/tickets/showTicket/7213
Description
Sites deployed from a prebuilt artifact have no
.gitdirectory on disk, so the server harvester's git detection finds nothing and posts an empty result. Those sites show up here with no origin and no tag, and with noGitReporow at all — which is whyapp:economics:sync-agreementskeeps reporting repositories it cannot link,deltag.aarhus.dkamong them. This is theDeployDetectionResultitem fromTODO.md.The deployment is the only party that knows the repository and tag, so it now reports them to
POST /api/deploy_results.Changes:
DeployResult— a new entity and endpoint, followingDetectionResult:Postwithstatus: 202, output: false, messenger: trueand a written-outopenapiblock. It is a source record, not derived data, so it is persisted and can be replayed. Typed fields (serverName,rootDir,repoUrl,tag,commit,pipelineUrl) rather than a JSON blob, withAssertconstraints that make the documented 422 real.DeployResultHandlerresolves the server by name, deduplicates by content hash the way detection results do, and hands off toDeployResultApplier. Routed straight toasync: unlikeDetectionResultit needs no synchronous hop, because the payload names its own server rather than relying on the security context.DeployResultApplierlinks the installation to the repository and tag, and is shared withapp:replay:deploy-resultsso a rebuild can restore what deployments reported.Installation::$codeSource(gitorartifact) records whether an installation is a git working copy or an unpacked release artifact, shown as aSourcecolumn and filter in the admin. It describes what the installation is, not which tool observed it, so it stays true regardless of reporter.GitHandlerno longer clears the tag of an artifact installation. The harvester reports an empty git result for those on every scan, and clearing the tag would not merely unlink it —RemovedRelationsListenerdeletes a git tag, and its repository, as soon as no installation points at it. That is the sharpest edge in this change and it has its own test.GitTagFactorygainsresolveGitTag(), extracted so deployments can reuse the repository and tag lookup without the working-copy fields. A deployment has no working tree, so it deliberately writes nogitChanges/gitChangesCount—ChangesFieldrenders0as a badge reading "clean checkout", which a deployment cannot claim.Authentication uses a key from the environment (
APP_WOODPECKER_API_KEY) rather than a row in the database, so rotating it touches no data and can move to the vault later without a code change. It is neither a user nor a server: it grantsROLE_DEPLOYERand unlocks this one endpoint. An unset key never authenticates.Two behaviours worth calling out, both deliberate:
Installation::$detectionResultis not nullable, and one invented here would be orphan-removed by the next directory scan anyway. A site deployed before its first hourly scan is picked up by the next deployment or by a replay.Screenshot of the result
Admin change is one added
Sourcecolumn and filter on the Installation list; no screenshot attached as the endpoint itself has no UI.Checklist
99 tests, 231 assertions. New coverage: API-level auth and validation (401 / 403 for a server key / 202 for the deploy key / 403 reading
/api/serverswith it / 422 on a blank tag), the authenticator's unset-key guard, the handler, the applier,GitHandler's guard, and an integration test against a real database asserting the deployed tag and itsGitReporow survive a harvester scan. Both regression tests were confirmed to fail without their fix.Additional comments or questions
Stacked on #111 — please merge that one first; GitHub will then retarget this to
develop. This branch contains its commit, andDeployResultApplierdepends on that fix: every redeployment of an already-known tag would otherwise link nothing.Once this is deployed, the Woodpecker side is itk-devops/woodpecker-ansible-plugin#14, which needs one follow-up commit to send these typed fields instead of the harvester-shaped envelope it currently sends.