Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CI: Tweak Cirrus build filter to allow tag pushes #699

Merged
merged 1 commit into from
Aug 31, 2023

Conversation

DeeDeeG
Copy link
Member

@DeeDeeG DeeDeeG commented Aug 31, 2023

Short Summary / Purpose

This is a really long PR body for a very short change. This is trying to align our Cirrus build filters to do what we want them to do -- limit builds only to cron (for Rolling) builds, along with one build per release during our Regular release process.

Identify the Bug

See this comment thread: #682 (review)

To summarize: the build filtering logic in .cirrus.yml at the moment seems to be slightly different from what was intended.

(This filtering logic is the main mechanism we use to restrict what circumstances Cirrus tasks run in, now that the free Cirrus usage has some significant upper limits placed on it per month.)

Description of the Change

In the .cirrus.yml CI config definition file, the part where we use only_if: to filter what conditions the tasks will run in... Check the Cirrus env var CIRRUS_TAG is non-empty, meaning the current build was triggered by a tag being pushed to this repo.

This, along with the existing cron build filter, would mean we only build for "cron builds or tag pushes." Which I think is about right.

Alternate Designs

See this whole thread for discussion: #682 (comment)

(This is a long section about various alternatives that I don't think are worth it, given the approach I actually went with seems at minimum just slightly better, IMO. Feel free to skip this section, if you want!)

CIRRUS_PR_LABELS == "regular_release" was the approach proposed just before I stumbled upon this one. But I feel like having to set a PR label is a little more cumbersome than having Cirrus just automatically build for when the tag is pushed. I think that would also require conscious timing/order of operations -- setting the PR label before publishing the PR or ideally just before pushing the "change version to 1.X.0 (no -dev)" commit. Otherwise (I think), the build's tasks will skip and no binaries will be produced... Furthermore, there is the risk of multiple builds happening per release and using double credits unintentionally/undesirably, since we usually do push a "re-add the -dev to the version string" commit before merging the version bump PR's...

As another option, I believe required_pr_labels: regular_release would wait for the label and only then trigger the tasks, which fixes the "requires some timing/order of operations" concern. But still requires a PR label, whereas this PR currently just needs a tag to be pushed, adding no manual work to the release flow. And the "PR label" filtering approach still risks a wasteful second build when doing the "remove -dev from the version string" commit we usually do at the end of the version bump PR's.

We also have a bunch of other Cirrus env vars we may be able to check, but I stopped looking into them, since this PR's approach seemed to be a better match than any of those. But for example, CIRRUS_RELEASE happens if you create a tag during the creation of a GitHub Release, which if we make the tag manually, as we usually do, won't work. (But side note, if we do start making the tag from, say the GitHub Releases web UI, the approach I took in this PR is still valid. And could enable us to automatically upload the binaries to the right raft release here at core repo!)

We could also look at CIRRUS_PR_TITLE or CIRRUS_PR_BODY and see if they include "Release" or something, but searching in arbitrary text is imprecise, and might risk running release-specific stuff where there wasn't actually an intent to do so, and risk wasting credits.

See: https://cirrus-ci.org/guide/writing-tasks/#environment-variables for all the various Cirrus env vars we could work with...

Possible Drawbacks

Building on every tag push means, if someone randomly pushed a tag without specifically intending to run a release, we would waste credits, and depending on how much automation is set up down the line, might automatically attempt to upload some binaries to a GitHub release. We should do a PSA for those with write access to please not push any random tags, but then again, people already don't do that, so... Also, we costed out our credit use very conservatively to stay within our limits. Chances are we could easily handle one or two, maybe even several branch pushes and still make it through the month in terms of credits.

But yeah, we should avoid pushing random tags if we go with this simple "on tag pushed" approach.

Verification Process

Admittedly not tested, but this aligns with the docs at https://cirrus-ci.org/guide/writing-tasks/#environment-variables.

It's also used in a real-world example Cirrus team pointed us to: https://github.com/cirruslabs/macos-image-templates/blob/59624221fec15db250bfcad9e68d0e8931d2ccdc/.cirrus.yml#L33 (From this discussion where @confused-Techie got some valuable info on how we could start limiting the builds: cirruslabs/cirrus-ci-docs#1223 (comment))

We will want to test this down the line, but testing it requires this config change being present on a tag that's pushed, so... I suppose I can push a tag off this branch to test it??? (And then delete said tag.)

TODO.

Release Notes

N/A

(Do we do Changelog entries for CI stuff???? I don't think we do. I dunno.)

We were trying to filter for a certain PR label before,
but inadvertently checked the wrong env var,
based on interpreting some guidance we got from Cirrus team.

In researching what it should be instead, it occurred to me we can
indeed use the `CIRRUS_TAG` env var to check for *any tag push*,
which should actually do pretty well at filtering for releases
after all, since releases are the only times we really push tags.
@confused-Techie
Copy link
Member

confused-Techie commented Aug 31, 2023

While overall this does sound really good, and I'm happy to read the docs as needed, one concern I do have.

When a new tag is published, which triggers cirrus to run, will it just run off the master copy? Since at that point the version won't be whatever the tag is within the package.json, unless that's being handled elsewhere, or otherwise Cirrus is smart enough to build from the commit that was tagged itself, which I hope the latter is true.

Just something we might want to be aware of during a test. Actually confirm the exact version string as reported by Pulsar.

But beyond that, thanks a ton for addressing this, as it definitely needs to be

@DeeDeeG
Copy link
Member Author

DeeDeeG commented Aug 31, 2023

otherwise Cirrus is smart enough to build from the commit that was tagged itself, which I hope the latter is true.

Yeah, that's how I read it, Cirrus takes the repo content overall from what triggers the build, but due to our setting on the dashboard it will use whatever CI config is on master.

Just something we might want to be aware of during a test. Actually confirm the exact version string as reported by Pulsar.

I can test now, and prove that the current master branch version of .cirrus.yml is respected, and therefore I expect the tasks to skip, if I tag off of this branch?

And/or I can temporarily toggle the dashboard setting and then tag, to try and test this PR's change working and actually running tasks.

@DeeDeeG
Copy link
Member Author

DeeDeeG commented Aug 31, 2023

Oops, I had set the dashboard wrong, it's doing its task filtering based on .cirrus.yml at the SHA that triggered the build. Not locking down to the version of .cirrus.yml from master branch. (Glad I was doing this PR and caught this!)

Incidentally, that means testing worked great to demonstrate this PR.

See these runs: https://cirrus-ci.com/github/pulsar-edit/pulsar/CI-tweak-Cirrus-build-filters

A view of four Cirrus builds, three green ones that are labeled as  completed  and are caused by tag pushes, one blue one labeled as  running  that is caused by a tag push

Three "skipped" builds for branch pushes, and one running build for the tag push for tag test-pr-699-1 at the tip of this branch. (I suppose this might cause a Rolling release or two if I don't cancel those tasks...)

EDIT to add: I need to go and properly lock down the Cirrus dashboard setting like I thought I had done already... Done.

ALSO: The rolling upload script was smart enough not to upload a Rolling! Very cool!

node ./rolling-release-binary-upload.js cirrus
Due to the absence of `CIRRUS_CRON` it seems this is not a rolling release...
Exiting without uploading binaries...

https://cirrus-ci.com/task/6004538386153472?logs=rolling_upload#L21

Copy link
Member

@confused-Techie confused-Techie left a comment

Choose a reason for hiding this comment

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

Well glad you were able to test this so quickly even if it came from a slight misconfiguration lol.

But super happy to see Cirrus is operating in my hoped way, and knowing that this looks great to me! And looks like this may be one of our last CI centered PRs needed for the next little bit, which is nice to see.

Super rad work on this one

@DeeDeeG
Copy link
Member Author

DeeDeeG commented Aug 31, 2023

Alright, thank you for the review, merging!

@DeeDeeG DeeDeeG merged commit a08121d into master Aug 31, 2023
@DeeDeeG DeeDeeG deleted the CI-tweak-Cirrus-build-filters branch August 31, 2023 07:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants