Skip to content

feat: link to the release a Create release step makes - #238

Open
NickJosevski wants to merge 5 commits into
mainfrom
nj/release-link
Open

NickJosevski wants to merge 5 commits into
mainfrom
nj/release-link

Conversation

@NickJosevski

Copy link
Copy Markdown
Contributor

The Create release step now points at what it made: the build log links to the release, and octopus.release.url / octopus.release.number are published for later steps.

release create --output-format json already returned the release id alongside the version the step was reading; with the space id (one space view call, skipped when the step is configured with a Spaces-N value) that gives the address Octopus itself reports as a release's Links.Web — verified against Octopus 2026.4.12 as {server}/app#/{SpaceId}/releases/{ReleaseId}.

Nothing on this path can fail the step: the space lookup is an optional command, and an unreadable CLI response costs the link and nothing else.

Only reaches steps on the new Go CLI (OCTOPUS_NEW_CLI or an OIDC connection) — legacy octo exposes no release id without replacing the step's readable log with JSON.

Tested with a new e2e (OctopusCreateReleaseLinkE2ETest) that asserts the logged link equals the release's own Links.Web and that a follow-on step can read the parameters back.

🤖 Generated with Claude Code

@github-actions github-actions Bot added the feat label Sep 7, 2026
@NickJosevski

Copy link
Copy Markdown
Contributor Author

Second slice pushed: the build page now shows the release too.

The step records each release it creates as a hidden build artifact (.teamcity/octopus/release-<runnerId>.properties, one per step) and the server reads those back into an Octopus Deploy tab on the build. That's the surface the current UI actually renders for a plugin — it hosts the tab inside its classic-UI adapter. Verified on the e2e stack (TeamCity 2025.03.3): the Sakura build overview has no slot for a build-summary fragment, so PlaceId.BUILD_SUMMARY alone would have been invisible to anyone not switching to the classic UI. Both surfaces are now covered: the tab, and the same link in the build summary on the classic page.

New OctopusReleaseLinkUiTest drives a browser and asserts the tab's iframe and the classic summary both link to the release's own Links.Web.

Getting the link onto the new UI's overview itself would need a JS plugin against the newer TeamCity API — happy to scope that separately.

@NickJosevski

Copy link
Copy Markdown
Contributor Author

Local testing

Ran the release link against a local Octopus (not the containerised free-tier one used by the e2e suite): a real project in a non-default space, on a recent build of the server. TeamCity server + agent came from the e2e fixture and reached the local instance over host.docker.internal. The API key was injected from a keychain-backed store, so it never appeared on a command line or in a log.

Five scenarios, all passing:

Scenario Result
Connection names the space Log line View this release in Octopus Deploy: <url>, where <url> equals the release's own Links.Web; octopus.release.url / octopus.release.number read back by a later step; one summary artifact published; the Octopus Deploy tab's href matches exactly
Connection gives the space id instead of the name Same link, and the space view lookup is skipped entirely — absent from the build log
Two Create release steps in one build Two summary artifacts; the tab lists both releases
Legacy octo path (no OCTOPUS_NEW_CLI) Release still created; no link, no summary artifact, no tab
Build with no Octopus step No Octopus Deploy tab at all

Worth noting:

  • The link shape is the one the server itself reports (/app#/<SpaceId>/releases/<ReleaseId>), now confirmed against a recent Octopus and in a space that isn't Spaces-1 — that's the case the space lookup exists for, and the one a hand-built URL would get wrong.
  • The build log never contains the API key (asserted).
  • Cleanup: the harness deletes the releases it creates. The instance was left as found — its pre-existing release only, no new projects.
  • Two failures during the session were in the harness's own assertions (a 404 when a build publishes no summaries at all, and miscounting filenames that appear three times each in the artifacts REST payload), not in the plugin.

Not covered locally: the classic build-summary surface, which only the container suite exercises (there's no local TeamCity set up, and its datadir is empty). The tab was verified through the current UI's iframe adapter both locally and in the container suite.

The local harness is uncommitted scratch — it hardcodes the local space, project and URL. Say the word and I'll parameterise it by environment variables and commit it as a repeatable local check.

@NickJosevski

Copy link
Copy Markdown
Contributor Author

Correction to the e2e note in docs/e2e-tests.md: I'd written that the five-project cap was "Octopus's free tier". It isn't.

  • octopus.com's free tier is 10 projects, 10 tenants, 10 machines, 10 users, 1 space — and needs a licence key the suite deliberately doesn't use (pricing, FAQ).
  • What the stack actually runs is the Community Edition (unlicensed). Asked directly, GET /api/licenses/licenses-current-status on the running container reports Projects: 5, Targets: 5, Tenants: 5, Spaces: 1, serial 00000-…, with the message "You are using the Community Edition of Octopus Server."

So the number five was right, the name wasn't. Fixed in b7c9230, which also drops "free tier" for "unlicensed / Community Edition" in the surrounding docs and in OctopusTeamCityStack's javadoc, where the same claim was already being made.

Note that the earlier test: commit message still says "free tier allows five projects at once" — wrong for the same reason. Left as-is rather than rewriting the branch's history; the docs are the part anyone reads.

@NickJosevski
NickJosevski force-pushed the nj/release-link branch 2 times, most recently from 3a709b1 to 742687f Compare September 17, 2026 08:06
NickJosevski and others added 5 commits September 17, 2026 21:43
The step already asked the CLI for JSON it only read a version out of; the
release id was in there too. With the space id (one `space view` call, skipped
when the step is configured with a `Spaces-N` value) that is the address
Octopus itself reports as a release's `Links.Web`, so the step now logs it and
publishes it as `octopus.release.url` and `octopus.release.number` for later
steps.

A link is a nicety on top of a release that already exists, so nothing on this
path can fail the step: the space lookup is an optional command, and an
unreadable response costs the link and nothing else.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The step records the release it created as a hidden build artifact, one file
per step, and the server reads those back to link to each release from an
"Octopus Deploy" tab on the build - the surface the current TeamCity UI renders
for a plugin, which hosts it in its classic-UI adapter. The classic build page
additionally carries the same link in the build's summary, which is the only
place that fragment can appear.

A hidden artifact rather than stored state so the record lives and is cleaned
up with the build it describes, and so the server needs no listener to catch it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Octopus's free tier allows five projects at once and the suite was already
using four, so a project per new test made the next test to provision fail with
"This would exceed the limits of your current license". The two release link
tests only need somewhere to make a release, so they share one project and keep
their own release versions apart.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
OidcPluginFixture already sends GITHUB_TOKEN when it has one, but the job never
passed it, so it asked for the OIDC plugin's latest release unauthenticated -
against a limit shared per IP across runners. Hitting it 403s the fixture, and
with it the whole shared stack's boot, failing every e2e test in seconds.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The note added with the shared-project change called the five-project cap
"Octopus's free tier". It is not: the advertised free tier allows ten projects
and needs a licence key, while the stack runs unlicensed, which is the
Community Edition. Its limits, as the running container reports them, are five
projects, five targets, five tenants and one space.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant