Back to Feed
article 2m read

The release proof that exited clean and printed nothing

A deploy check run through the blue/green release symlink never ran its main function, because the module's own filename had the symlink resolved and the command line did not, so it exited zero with no output.

Article DepthPractice

Flow

Three changes to the deploy check

The last one catches any script that does nothing.

  1. 1Compare real paths

    Follow links on both sides before deciding the script should run.

  2. 2Run from the app folder

    Match the conditions of the hand run that worked.

  3. 3No output means failure

    A clean exit with nothing printed is rejected with a clear message.

One deploy step failed in a strange way. It runs a small check script on the server. The script prints a line of JSON that says the archive is fine, and the deploy reads it. This time there was no JSON. The script had ended with a success code and printed nothing. Run by hand, the same script worked.

The cause was a symlink. Each release gets its own folder, and the app path is a link to the live one. The deploy runs the script through that link.

At the bottom of the script is a common check: only do the work if this file is the one Node was told to run. It did that by comparing two paths as plain text. One path came from the command line, and it still had the link in it. The other was the file's own path, and Node had already followed the link to the real folder. So the two never matched. The script did nothing, and it ended with success because nothing went wrong.

The agent made three changes:

  • The check now compares the real paths, with links followed on both sides.
  • The deploy runs the script from inside the app folder.
  • The deploy treats "success, but no output" as a failure, with a clear message.

There's a test that builds a real linked folder and proves the check works through it.

If you write scripts like this, two things help. Compare real paths, not the text someone typed. And never let a check pass just because it exited cleanly. Make it show you a result.

What bugs me is how close this came to passing. The deploy only failed because it read the output. A step that looked only at the exit code would have called the archive healthy. That's why the "no output" rule matters most to me. It catches the next script that does nothing.

I'd bet other scripts have the same check. That's next.

Keep reading

Pick up a connected idea or branch into a nearby one.

3 paths forward