Skip to content

feat: install script to check for hard stops - #4489

Open
aldy505 wants to merge 13 commits into
masterfrom
aldy505/feat/check-hard-stop
Open

aldy505 wants to merge 13 commits into
masterfrom
aldy505/feat/check-hard-stop

Conversation

@aldy505

@aldy505 aldy505 commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

The idea came from Discord, and Alex (stayalive) lay out a very good approach on this: https://discord.com/channels/621778831602221064/796028405833007104/1541789134006259814

Comment thread install/check-hard-stop.sh Outdated
Comment thread install/check-hard-stop.sh Outdated
Comment thread install/check-hard-stop.sh Outdated
Comment thread install/check-hard-stop.sh Outdated
Comment thread install/check-hard-stop.sh
Comment thread install/check-hard-stop.sh Outdated
Comment thread install/check-hard-stop.sh Outdated
Comment thread install/check-hard-stop.sh Outdated
Comment thread install/check-hard-stop.sh Outdated
@aldy505

aldy505 commented Aug 25, 2026 •

Copy link
Copy Markdown
Collaborator Author

@aminvakil apparently, exit 0 terminates the install script. do you have any other suggestion for this? I want to avoid hadouken pattern.

EDIT; nevermind I just read this #4489 (comment), sorry about that

Comment thread install/check-hard-stop.sh Outdated
Comment thread install/check-hard-stop.sh Outdated
@BYK

BYK commented Aug 25, 2026

Copy link
Copy Markdown
Member

Just dropping this here: #3878 (review)

Overall, I think this is pretty good but we need a shared place and format to have the hard-stops so docs and the repo does not diverge. I'd propose JSON in a well-known location like the docs repo or this repo, and reading it with jq in the install script

@aldy505

aldy505 commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator Author

Just dropping this here: #3878 (review)

Overall, I think this is pretty good but we need a shared place and format to have the hard-stops so docs and the repo does not diverge. I'd propose JSON in a well-known location like the docs repo or this repo, and reading it with jq in the install script

@BYK Yeah I remember about your comment. I don't know where the "shared place" should be. I don't want to have it on sentry, because I don't want to pull any image first, just for doing this. At the end of the day, I would think having these two separate would be good.

And yes, there will always be a maintenance burden for this one.

Comment thread install/check-hard-stop.sh Outdated
Comment thread install/check-hard-stop.sh Outdated
Comment thread install/check-hard-stop.sh Outdated
Comment thread install/check-hard-stop.sh Outdated
Comment thread install/check-hard-stop.sh Outdated
Comment thread install/check-hard-stop.sh Outdated
@BYK

BYK commented Aug 26, 2026

Copy link
Copy Markdown
Member

I don't want to have it on sentry, because I don't want to pull any image first, just for doing this

Not sure we are on the same page. My proposal is having this information in a separate, dedicated JSON file in this repo and then the docs repo fetching it at build time.

@aldy505

aldy505 commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator Author

I don't want to have it on sentry, because I don't want to pull any image first, just for doing this

Not sure we are on the same page. My proposal is having this information in a separate, dedicated JSON file in this repo and then the docs repo fetching it at build time.

Aaaaaahhhhhh, that makes sense. I dunno how to do it on the docs repo, but making a JSON file here would be doable.

Comment thread install/check-hard-stop.sh Outdated

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread install/check-hard-stop.sh Outdated
@aldy505
aldy505 added this pull request to stack #4507 September 13, 2026 15:09
@aldy505
aldy505 requested review from BYK and aminvakil September 13, 2026 15:25
@aldy505
aldy505 force-pushed the aldy505/feat/check-hard-stop branch from 9b35c7d to 2472e2c Compare September 13, 2026 15:26
Comment thread install/check-hard-stop.sh Outdated

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread install/check-hard-stop.sh Outdated
@aldy505 aldy505 linked an issue Sep 24, 2026 that may be closed by this pull request
@mhkarimi1383

Copy link
Copy Markdown

I think it's better to be on the Sentry's main source code in database migration part, not in install scripts, but it's better than nothing :)

@aldy505

aldy505 commented Sep 24, 2026

Copy link
Copy Markdown
Collaborator Author

I think it's better to be on the Sentry's main source code in database migration part, not in install scripts, but it's better than nothing :)

Sentry's main source code does not have the concept of "hard stop", as they're always deploying code from the "master" branch every hour.

@mhkarimi1383

Copy link
Copy Markdown

But hard stop should be handled in other installation methods (like k8s)

@aminvakil

Copy link
Copy Markdown
Collaborator

But hard stop should be handled in other installation methods (like k8s)

There is no other installation methods supported, k8s support is outside of scope of getsentry.

Also you should really read release notes before upgrading 😉

Comment thread install/check-hard-stop.sh Outdated
# version is below any of them.
local _wrote_version=0
for hard_stop in "${hard_stops[@]}"; do
compare_result=$(compare_calver "$current_version" "$hard_stop")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd suggest using existing vergte function, also cursor and sentry bots about returning exit statuses are correct.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I don't think that is an equivalent function, as I need a detailed response rather than just a boolean (coming from the response of vergte)

Comment thread install/check-hard-stop.sh Outdated
local _wrote_version=0
for hard_stop in "${hard_stops[@]}"; do
compare_result=$(compare_calver "$current_version" "$hard_stop")
if [[ "$compare_result" == 0 ]]; then

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm not sure if I understood this correctly, but let's say we are going from 26.5.0 to 26.8.0 and 26.7.0 is a hard-stop.

Doesn't this break outside of loop as soon as it sees 26.6.0 which is fine and not a hard-stop? never reaching 26.7.0?

@aminvakil aminvakil left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Would you please address bots comments and mention me again afterwards?

@jamgregory

Copy link
Copy Markdown

Also you should really read release notes before upgrading 😉

I'll just point out that I had read the release notes during our more recent upgrade and had still missed that 26.7.0 was a hard stop. It would still be preferable for the script to alert you to this, just in case you accidentally miss it.

Comment thread install/check-hard-stop.sh Outdated
@github-actions

github-actions Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Coverage Results 📊

✅ 22 passed | Total: 22 | Pass Rate: 100% | Execution Time: 11m 3s

📊 Comparison with Base Branch

Metric Change
Total Tests —
Passed Tests —
Failed Tests —
Skipped Tests —

✨ Test counts unchanged from base.

All tests are passing successfully.

✅ Patch coverage is 100.00% (no changed executable lines found; target 50%).
Project statement coverage is 95.54% (unchanged from base (9aa721e) to head (2f43916)).

Coverage diff
@@            Coverage Diff             @@
##        master     #4489       +/-##
==========================================
  Coverage    95.54%    95.54%        —%
==========================================
  Files            5         5         —
  Tracked lines       336       336         —
  Branches         0         0         —
==========================================
  Hits           321       321         —
  Misses          15        15         —
  Partials         0         0         —

Generated by Coverage Action

Comment thread install/check-hard-stop.sh
Comment thread install/check-hard-stop.sh Outdated
Comment thread install/check-hard-stop.sh Outdated
# Usage: compare_calver "1.2.3" "1.2.4"
# Returns: -1 if first < second, 0 if equal, 1 if first > second
#
# This bit is written by Claude Haiku 4.5.

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.

Haiku 4.5? What is this, the stone age? Use Luna at least 🤣

Comment thread hard-stop.json
@@ -0,0 +1,198 @@
# The idea of this file is to prevent users from skipping a hard stop.
# This is done by creating a file in /var/run/sentry-hard-stop (or anything set
# in HARD_STOP_FILE) and checking for its existence before. If the file exists,

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.

I'm not sure if I like the "hard stop file" approach. Why can we not infer the previous version from the sentry image/instance itself? This is additional state we need to keep track of now.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

How? We don't have sentry --version' kind of thing. Also this is being run after the user changed their .env` values.

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.

We have these labels baked into the image which we can extend to versions or use to derive versions: https://github.com/getsentry/sentry/blob/c4bca2967197bc758abb1bc141c42f75902814d7/self-hosted/Dockerfile#L143-L145

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I don't think we can fetch that. This works: docker inspect --format='{{index .Config.Labels "org.opencontainers.image.version"}}' ghcr.io/getsentry/sentry:26.9.0, but it outputs 91e940e6fe4df840c91d865b9d29df9a1b044faf rather than 26.9.0.

Also, we will never know the actual image being used, we need to use docker compose for that.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Actuallyyy, we can do this:

$ docker compose images --format json | jq 'first(.[] | select(.Repository == "ghcr.io/getsentry/snuba")) | .Tag'
"26.9.0"

Can't do that with getsentry/sentry because of this:

  {
    "ID": "sha256:3e697ae50aec8548451fa0c4e75e906c69ce8fe3caf94c675bf924b3b00bb4db",
    "ContainerName": "sentry-self-hosted-taskscheduler-1",
    "Repository": "sentry-self-hosted-local",
    "Tag": "latest",
    "Platform": "linux/amd64",
    "Size": 1406387641,
    "Created": "2026-09-16T21:19:42.544492665+07:00",
    "LastTagTime": "2026-09-17T07:57:24.173640312+07:00"
  }

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.

Comment thread install/check-hard-stop.sh Outdated

# Helper function to parse version components
# BASH_REMATCH requires Bash 3.0+
_parse_version_components() {

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.

Don't we already have these helpers somewhere for Docker version checks etc? We shouldn't be repeating this logic.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I didnt know. Probably would take another look at vergte, that Amin pointed out a few days ago.

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.

Yeah, we should just consolidate the logic.

Comment thread install/check-hard-stop.sh

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread install/check-hard-stop.sh
Comment thread install/check-hard-stop.sh Outdated
@aldy505
aldy505 requested review from BYK and aminvakil October 4, 2026 09:36

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0a605e1. Configure here.

fi

if [[ -z "$new_version" ]]; then
new_version=$(grep -E '^SENTRY_IMAGE=' .env | sed 's/^.*=//' | cut -d: -f2 || true)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Image tag parsed from wrong field

High Severity

cut -d: -f2 splits on the colon in ghcr.io, so new_version becomes the image path rather than the tag. That value then fails the CalVer length check, and the hard-stop logic never runs for the default SENTRY_IMAGE.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0a605e1. Configure here.

if [[ "$current_version" == "$new_version" ]]; then
break
elif vergte "$hard_stop" "$current_version"; then
if vergte "$new_version" "$hard_stop"; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Inclusive comparison flags valid upgrades

High Severity

vergte treats equality as a skipped hard stop, so upgrading to or away from a hard-stop version still triggers the warning. The prompt defaults to no and therefore cancels a valid upgrade.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0a605e1. Configure here.

echo "--------------------------------------------------------------------------------"
else
# We use snuba image because we don't rebuild the image, and it preserves
current_version=$($dc images --format json | $jq -r 'first(.[] | select(.Repository == "ghcr.io/getsentry/snuba")) | .Tag')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing snuba image aborts install

High Severity

$dc images lists only created containers, and jq first exits non-zero when no ghcr.io/getsentry/snuba image is present. Under set -e that aborts first-time installs and upgrades after containers were removed.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0a605e1. Configure here.

if [[ "$current_version" == "$new_version" ]]; then
break
elif vergte "$hard_stop" "$current_version"; then
if vergte "$new_version" "$hard_stop"; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The script incorrectly warns users they are skipping a hard-stop version when they are upgrading exactly to it, due to a >= check instead of >.
Severity: MEDIUM

Suggested Fix

Change the version comparison at line 107 from vergte (greater than or equal to) to a strict greater-than check. This will ensure the warning only triggers when the new_version is actually newer than the hard_stop version, not equal to it.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: install/check-hard-stop.sh#L107

Potential issue: The script uses `vergte` (version greater than or equal to) at line 107
to check if the `new_version` skips a `hard_stop` version. This comparison incorrectly
returns true when the `new_version` is exactly equal to the `hard_stop` version. As a
result, a user correctly upgrading *to* a required hard-stop version will receive a
false and confusing warning message stating they are skipping the version they are
trying to install. This will happen for every valid upgrade to any of the listed
hard-stop versions.

echo "Good luck."
echo
echo "--------------------------------------------------------------------------------"
elif [[ "${#new_version}" -gt 7 ]]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The CalVer length check (${#new_version} -gt 7) is too strict, causing valid versions to be flagged as invalid and silently skipping the hard-stop check.
Severity: HIGH

Suggested Fix

Relax the version string length check at line 70 to accommodate valid CalVer formats that can be longer than 7 characters, such as those with two-digit months or patch numbers (e.g., YY.MM.DD).

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: install/check-hard-stop.sh#L70

Potential issue: A length check at line 70 (`${#new_version} -gt 7`) intended to
validate CalVer versions is too restrictive. Valid Sentry CalVer strings can exceed 7
characters (e.g., `24.12.10` is 8 characters). When a user tries to upgrade to a valid
version with a string longer than 7 characters, the script incorrectly identifies it as
an invalid format. This causes the script to silently skip the entire hard-stop
validation logic, potentially allowing a user to upgrade past a required hard-stop
without any warning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Migration Hard Stops inforcement

5 participants