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

RUMM-1667 Enhance release automation #636

Merged
merged 6 commits into from
Oct 18, 2021

Conversation

ncreated
Copy link
Member

@ncreated ncreated commented Oct 14, 2021

What and why?

📦 This PR proposes enhancement to our release automation model. Compared to previous model:

  • It no longer creates Datadog-x.y.z.zip archive in current directory, instead it clones the repo to temporary folder which ensures clean state for building XCFrameworks. It removes the need for prepare() and cleanup() operations and guarantees that no dirty artefacts will be included in the .zip (in 1.7.0, 1.7.1 and 1.8.0-beta1 we accidentally included HTTPServerMock.xcframework).
  • It runs integrity checks to ensure that sdk_version and spec.version match the git tag and validates the content of produced Datadog-x.y.z.zip archive.
  • It supports --dry-run mode for testing and debugging locally and on CI (with DD_RELEASE_DRY_RUN=1 ENV).
  • It allows selective run for particular release tags (also on CI) which will be necessary for fixing 1.7.0, 1.7.1 and 1.8.0-beta1 GH assets.

How?

Updated Bitrise pipelnie

I reshaped our Bitrise CI pipeline to spin off two distinct jobs, one for publishing GH Release asset, one for pushing pods:

tagged_commit:               --- (tests) ---> ✅
publish_github_asset:                       ↘ --(make .zip + validate + upload)--> ✅
publish_cocoapods_podspecs:                 ↘ --(lint specs + push specs)-----------------------> ✅

I used the official Bitrise Start Build step instead of calling Bitrise API with curl (it gives us ENV propagation from tagged_commit to child jobs for free). It is possible to support Github Check by making the tagged_commit await child jobs completion, but in our case this will always end up with a CI timeout (90min) as Cocoapods specs push might take ~1h. Instead, eventual failure from child jobs is reported to our Slack channel.

New CLI tooling

I replaced Bash scripts with more flexible Python CLI tool:

❯ ./tools/distribution/release.py -h
usage: release.py [-h] [--only-github] [--only-cocoapods] [--overwrite-github] [--dry-run] git_tag

positional arguments:
  git_tag             Git tag name.

optional arguments:
  -h, --help          show this help message and exit
  --only-github       Only publish GH Release asset.
  --only-cocoapods    Only publish Cocoapods podspecs.
  --overwrite-github  Overwrite existing GH Release asset.
  --dry-run           Run validation but skip publishing.

It uses python3 and no pip dependencies. The --dry-run option allows for local and remote (DD_RELEASE_DRY_RUN=1) debugging. All options have their ENV counterpart, meaning that it can be run for any release tag locally and on CI.

The tool itself is simple: it makes, validates and publishes GH Release asset and / or Cocoapod specs, e.g.:

gh_asset = GHAsset()  # make the `.zip`
gh_asset.validate(git_tag=git_tag)  # validate it
gh_asset.publish(git_tag=git_tag, overwrite_existing=overwrite_github, dry_run=dry_run)  # upload to GH

Example CI logs for --dry-run: publishing GH Asset, publishing CP specs.

Review checklist

  • Feature or bugfix MUST have appropriate tests (unit, integration)
  • Make sure each commit and the PR mention the Issue number or JIRA reference

This tool is safer (it always starts with a clean repo state instead of resetting
altered state) and more flexible (both GH and CP artifacts can be published
for any tag in the repo, not only for the current tag).
One for GH Release assset and one for Cocoapods specs.
Remove parts of the release automation replaced with `release.py` and
additions to `bitrise.yml`.
@ncreated ncreated changed the title RUMM-1667 Enhance SDK release automation RUMM-1667 Enhance release automation Oct 14, 2021
@ncreated ncreated marked this pull request as ready for review October 14, 2021 11:45
@ncreated ncreated requested a review from a team as a code owner October 14, 2021 11:45
Comment on lines +77 to +78
shell(f'pod spec lint --silent --allow-warnings {self.__file_name}', skip=dry_run)
shell(f'pod trunk push --allow-warnings {self.__file_name}', skip=dry_run)
Copy link
Member

Choose a reason for hiding this comment

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

I think pod trunk push performs the same validation as pod spec lint.

Copy link
Member

Choose a reason for hiding this comment

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

Yes they both perform this validator. So you could just call pod trunk push.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agree 👍 , however I was trying to optimize for the CI log clarity here. Note, that we're calling pod spec lint with the --silent option and only calling verbose pod trunk push once after we know pushing will pass. Given that we know pod spec lint will fail for dozen of times, this should give us minimal log with maximum verbosity:

attempt 1: `pod spec lint` verbose failure 
attempt 2: `pod spec lint` silent failure 
attempt 3: `pod spec lint` silent failure 
...
attempt N: `pod spec lint` silent pass
attempt N+1: `pod trunk push` verbose pass 

I don't think we can use only pod trunk push to achieve the same, hence the question is if we want to optimize for CI speed (one redundant pod spec lint) or CI log clarity. WDYT?

Copy link
Member Author

@ncreated ncreated Oct 15, 2021

Choose a reason for hiding this comment

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

Well, actually we can have both by adding a bit more complexity to this tool and capturing shell('') output along with its result. Then we will control which output to print in the log. So this is a third option to consider.

Copy link
Member

Choose a reason for hiding this comment

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

Ah I see, I didn't catch the logic at first glance! I'm all for simplicity, if we are not too concern about build time I'm good with it 👍

@ncreated ncreated requested review from buranmert and maxep October 15, 2021 11:19
Copy link
Member

@maxep maxep left a comment

Choose a reason for hiding this comment

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

🐍 ⭐

@ncreated
Copy link
Member Author

I added an improvement to always build our dependencies from source, which leads to producing minimal GH Asset (with only the architecture slices we need):

- shell('carthage bootstrap --no-build')
- shell('carthage build --platform iOS --use-xcframeworks --no-skip-current')
+ shell('carthage bootstrap --platform iOS --no-build')
+ shell('carthage build --platform iOS --use-xcframeworks --no-use-binaries --no-skip-current')

Also, added additional log on the XCFrameworks details. I tried with 1.7.1 and --dry-run:

→ details on bundled `XCFrameworks`:
   - /Kronos.xcframework/ios-arm64_i386_x86_64-simulator
   - /Kronos.xcframework/Info.plist
   - /Kronos.xcframework/ios-arm64_armv7
   - /DatadogCrashReporting.xcframework/ios-x86_64-simulator
   - /DatadogCrashReporting.xcframework/ios-arm64
   - /DatadogCrashReporting.xcframework/Info.plist
   - /DatadogObjc.xcframework/ios-arm64_x86_64-simulator
   - /DatadogObjc.xcframework/ios-arm64
   - /DatadogObjc.xcframework/Info.plist
   - /Datadog.xcframework/ios-arm64_x86_64-simulator
   - /Datadog.xcframework/ios-arm64
   - /Datadog.xcframework/Info.plist
   - /CrashReporter.xcframework/ios-arm64_i386_x86_64-simulator
   - /CrashReporter.xcframework/ios-arm64_arm64e_armv7_armv7s
   - /CrashReporter.xcframework/Info.plist

Copy link
Member

@maxep maxep left a comment

Choose a reason for hiding this comment

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

perfect 👌

@ncreated ncreated merged commit 0ebcb7f into master Oct 18, 2021
@ncreated ncreated deleted the ncreated/RUMM-1667-fix-release-automation-issues branch October 18, 2021 12:30
ncreated added a commit that referenced this pull request Nov 5, 2021
…utomation-issues

RUMM-1667 Enhance release automation

(cherry picked from commit 0ebcb7f)
ncreated added a commit that referenced this pull request Nov 5, 2021
…utomation-issues

RUMM-1667 Enhance release automation

(cherry picked from commit 0ebcb7f)
ncreated added a commit that referenced this pull request Nov 8, 2021
…utomation-issues

RUMM-1667 Enhance release automation

(cherry picked from commit 0ebcb7f)
ncreated added a commit that referenced this pull request Nov 8, 2021
…utomation-issues

RUMM-1667 Enhance release automation

(cherry picked from commit 0ebcb7f)
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.

3 participants