← Blog Developers · 4 min read

Versioning links in CI so releases do not break them

Links that point at versioned artefacts need to be updated by the same pipeline that produces the artefacts.

By ShortFreeURL Team · 2 September 2026

A release produces artefacts at versioned locations: a downloadable binary, a changelog anchor, a documentation page for that version, a container image tag. Around those artefacts sit links published elsewhere — in a README, in an email, in a dashboard, on a status page. Every release, somebody is supposed to update those links, and after a few releases somebody has not.

The failure is quiet. The link still resolves, to the previous version, and readers get an artefact that is one or three releases behind without any indication that they should look further. Treating link updates as a manual post-release chore guarantees this outcome, because manual post-release chores are done reliably for about two months.

Two kinds of link exist and confusing them causes most of the trouble. A stable link always points at the current release: latest download, current documentation, newest changelog. A pinned link points permanently at one version and must never move, because it appears in a release note, a support ticket or a customer integration that describes that specific version.

Write the distinction into your slug convention so it is visible. Something ending in the word latest and something containing a version number are self-documenting, and nobody will accidentally repoint the second while updating the first. A pipeline that can only create pinned links and update stable ones cannot produce the worst mistake.

The moment the pipeline knows the version, it knows every URL that version will have. That is the right moment to create the pinned links, because the values are present in the environment and no human has to transcribe them. Creating them later, from a wiki page, reintroduces the transcription error you were trying to eliminate.

Emit them as part of the build output so the release job can include them in release notes and announcements without a second lookup. The link becomes an artefact of the release like any other, produced once and referenced everywhere.

The stable link should move at the end of the pipeline, after the artefact is genuinely available at its destination, not at the start when the version number is assigned. A build that fails after tagging but before publishing would otherwise leave the latest link pointing at something that does not exist.

Order the steps so the last thing that happens is the repoint, and make it conditional on the publish step having succeeded. This single ordering decision prevents the most user-visible release failure available: a download link that 404s for everyone during the window before someone notices.

Make the operation idempotent

Pipelines are re-run. A partial failure, a manual retry, a re-tag of the same version — all of these will execute the link steps again. Creating a pinned link must therefore treat an existing link with the same slug and the same destination as success, not as a conflict, and updating a stable link must be safe to repeat.

Where the platform returns a conflict for an existing slug, check whether the existing destination matches what you intended. If it does, proceed. If it does not, fail loudly, because that is a genuine collision and silently overwriting it is how a pinned link stops being pinned.

Keep the credential narrow and out of the log

The pipeline needs an API token that can create and update links. Scope it to the specific domain used for releases and give it no ability to touch marketing links or account settings. Store it in the CI secret store and reference it as an environment variable rather than passing it on a command line, where it can appear in process listings and in verbose logs.

Log the slug and the destination, never the token or the full request. Rotate the credential on a schedule, and confirm that the rotation was picked up by running a release, because a token that expired quietly will present itself as a mysterious release failure months later.

Assert the result rather than trusting the API response

A successful API call means the platform accepted your request. It does not prove that a browser following the link reaches the artefact. Add a verification step that fetches each link the pipeline touched and asserts both the status code and the final destination, and fail the build if either is wrong.

This catches the cases the API cannot: a destination that was published to the wrong path, a bucket permission that was not applied, a CDN that has not yet picked up the new object. It costs a few seconds and it is the difference between believing the release is correct and knowing it.

Keep the mapping in the repository

The list of links a release owns should live in a file in the repository next to the code, not in the pipeline configuration and not in someone's account. A simple file naming each logical link, its slug pattern and its destination template makes the whole scheme reviewable in a pull request and recoverable if the CI system is rebuilt.

It also gives you the audit you will want later. When someone asks why a link points where it does, the answer is a commit with a message and an author, rather than an edit made in a web interface by an account that no longer exists.

Related posts

Start Free — no credit card

The free plan includes 1,000 links, 6 custom domains and 50,000 tracked clicks a month, free forever. Choose a free subdomain from six shared domains. Paid plans start at $4 a month when you outgrow it, and you keep everything you have built.