feat: experiment badge, target stats and license commands - #76
Merged
Merged
Conversation
How many targets of each type the platform knows was only visible in the UI's landscape. `target stats` prints the counts of the tenant, sorted by type, or with -q only of the targets matching a target query, which is the quick way to see what a query would hit before putting it into an experiment or an environment. -t json|yaml and --jq get the platform's object as it is. The endpoint counts over the whole tenant and takes no environment, so unlike `target query` there is no -e.
An admin had to open the UI to see when the license expires and how close the tenant is to a limit such as services or environments. `license show` prints the license, a warning when it expired or expires within 30 days, the limited features with their usage, over-limit ones in red, and the features that are simply included. -t json|yaml and --jq get the platform's summary as it is. The usage report is a zip archive holding one archive per license period (the license as JSON, the usage as CSV), not a value -t could print, so it is its own command, `license report`, which writes it like `execution artifact download` writes artifacts: under the name the platform gives it, reduced to one path segment, or to -o. Both need an admin access token, and say so on 403 as `audit-log` does.
A status badge in a README shows whether an experiment's latest run passed, but building its URL meant finding the badge dialog in the UI or reading the docs for the tenantKey parameter. `experiment badge -k KEY` prints the snippet: Markdown by default, --format html or url, --scale for the image size; --tag prints the badge of a tag, which invites to create the experiment while none has the tag. -t json|yaml and --jq get the image URL, link and both snippets. The badge endpoints are public and take only the tenant key, so nothing secret ends up in a README; the help says what the badge shows to anyone who knows that key. The access token does not name its tenant, and the license summary is the only response that does, so the key is read from it with an admin token, and --tenant gives it otherwise. The platform answers a badge request made with a token for the token's tenant, whatever tenantKey says, and a missing experiment's badge is an image saying "not found" with 200. So the experiment is looked up first, and the badge is fetched once without the token, as a README would load it: a wrong tenant key fails the command instead of rendering as a broken image.
Both built the request and set the User-Agent on their own, so a change to one could miss the other. newRequest builds it; Get then adds the access token.
…ecks -t first The badge of another tenant's experiment is an image saying "not found", sent with 200, so the anonymous check passed and the command printed a broken badge. When the license names the token's tenant, a --tenant that differs is refused; without an admin token the license cannot be read and the given key is taken as before. A wrong -t was only reported by the printing, after up to three requests; it is now checked first, in target stats too. -t prints every format at once, so --format is refused with it instead of being ignored, and --format no longer defaults to markdown in the flag itself, which would make it look given.
…w reads right license report wrote the name from Content-Disposition into the current directory and replaced any file of that name, dotfiles included: the name is the platform's choice, not the user's. It is now created only if it does not exist, a leading dot is dropped, and a name reducing to nothing becomes license-report.zip. A file named with -o is still overwritten, as asked. license show left a double space for an empty order number and "of tenant ," for a null tenant key; the sentence is built from the parts present. It said "1 days". The limit shown was the first field present, so a soft-limit feature also sending a hard limit showed the hard one; the feature's type now decides. Usage at a hard limit is highlighted too, since nothing more can be added. A wrong -t is reported before the request.
# Conflicts: # CHANGELOG.md
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Three read-only commands covering API areas the CLI didn't have yet. One commit each.
steadybit experiment badge -k KEYprints a ready-to-paste status badge for a README:--format markdown|html|url, with Markdown the default;--scale;--tag(with--create-caption) for the tag-linked badge, which invites to create an experiment while none has the tag;--tenant;-t json|yaml, which--jqapplies to.tenantKey, never the token. The command fetches the badge without the token, as a README would, to check the URL works. With a token, the platform ignores a wrong tenant key, so an authenticated check would pass on a badge that breaks in the README. This is the one change outside the new packages:platform.Client.GetAnonymously, which skipsauthorize, and a test asserts noAuthorizationheader is sent. What a badge does expose: anyone with the tenant key (it's in every platform URL) can see that an experiment key exists and how its last run ended. The help says so.Experiment X not found.when there is none.GET /api/license, the only endpoint that tells a token its tenant. That needs an admin token; otherwise pass--tenant.steadybit target stats [-q QUERY]GET/POST /api/target-stats) as a table sorted by type, or-t json|yaml.-e.steadybit license show/steadybit license reportshowprints a one-line summary (license, tenant, validity, plus "expires in N days" when it's under 30), a table of the limits with their usage (red when over), and the included features.reportdownloads the usage report, which is a zip. It's a subcommand rather than a flag because-tcan't print binary data. It saves under the platform's filename, reduced to one path segment, or to-o FILE, asexecution artifact downloaddoes.Surprises from the API, handled:
target-statsreturns its map in random order, and the license'sfeaturestoo; both are sorted.Testing
--jq, empty results, 403/404/422, a wrong tenant, noAuthorizationheader on the badge check, and a report filename that can't leave the directory.go test -race ./...andgo vet(alsoGOOS=windows) pass.200 image/svg+xmlwithout a token.target statscounts 28,059 targets, andlicense show/license reportwork (the downloaded report was deleted).Open questions
/experiments/edit/KEY?tenant=…&team=…); the docs show a different one.