Tomacco

Docs Operation reference release operations

release operations#

7 operations. Generated from assets/operations.json; all areas.

On this page (7)

release.keystore#

Create signing key

Create a new RSA-4096 PKCS12 signing identity. Existing files are never overwritten.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
password_filestringyesOwner-only file containing one password; never stored in job arguments
aliasstringyesmatching [A-Za-z0-9_.-]{1,100}
outputstringyes
distinguished_namestring"CN=Tomacco Development"non-empty, up to 500 characters
validity_daysinteger10000365 to 36500
tomaccoctl call release.keystore '{"output":"<output>","password_file":"<password_file>","alias":"<alias>"}'

release.sign#

Sign Android release

Align APKs for 16 KiB pages, sign APK/AAB, verify signatures, then atomically publish a new artifact.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
password_filestringyesOwner-only file containing one password; never stored in job arguments
aliasstringyesmatching [A-Za-z0-9_.-]{1,100}
keystorestringyes
pathstringyes
outputstringyes
key_password_filestringOptional distinct key password; defaults to the keystore password
tomaccoctl call release.sign '{"path":"<path>","output":"<output>","keystore":"<keystore>","password_file":"<password_file>","alias":"<alias>"}'

release.verify#

Verify release signature

Verify APK or AAB integrity and show signing certificate diagnostics.

Annotations: read-only, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
pathstringyes
tomaccoctl call release.verify '{"path":"<path>"}'

release.signing_health#

Check signing keys

Read every key of an Android keystore, or one alias, with keytool: owner, certificate validity and days left, key algorithm and size, signature algorithm and SHA-256 fingerprint. Findings: expired (error), expires_soon within warn_days, play_minimum_validity for a key that ends before 22 October 2033 as Google Play requires of app signing keys, weak_key under 2048 bits (error), dsa_key, weak_signature for MD5 or SHA-1. Given the upload and app signing certificate fingerprints from Play Console's app integrity page, each key gets play_role upload, app_signing or none; not_play_key is an error. artifact checks that an APK or AAB is signed with a key of this keystore. Reads files only and contacts no store.

Annotations: read-only, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
keystorestringyesnon-empty; Absolute path of the keystore (PKCS12 or JKS)
password_filestringyesOwner-only file containing the keystore password; never stored in job arguments
aliasstring""Check only this key; empty checks every entry
warn_daysinteger3651 to 36500; Warn about keys that expire within this many days
upload_certificate_sha256string""SHA-256 fingerprint of the upload key certificate as Play Console shows it
app_signing_certificate_sha256string""SHA-256 fingerprint of the app signing key certificate as Play Console shows it
artifactstring""Absolute path of an APK or AAB whose signer should be a key of this keystore
tomaccoctl call release.signing_health '{"keystore":"<keystore>","password_file":"<password_file>"}'

release.version#

Set app version

Set one version name and build number in every version file of a project at once: pubspec.yaml, Expo's app.json (expo.version, android.versionCode, ios.buildNumber), the package.json of a React Native or Expo app, the Android app's Gradle file with the versions catalog entry or gradle.properties key it reads, and the Info.plist an xtool.yml names. bump computes the next version from the current one and the build number as the highest current one plus 1. dry_run lists the changes without writing. Each changed file gets a recoverable backup; a version only the build computes is refused.

Annotations: destructive, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
pathstringyesAbsolute path of the project root
versionstringNew version name, major.minor.patch with an optional -suffix; requires build_number
build_numberinteger1 to 2100000000; New versionCode and build number; with bump, defaults to the highest current one plus 1
bumpstringone of major, minor, patch, build; Raise this part of the current version instead of passing version; build keeps the version and raises only the build number
dry_runbooleanfalseReport the changes without writing
tomaccoctl call release.version '{"path":"<path>"}'

release.notes#

Write Play release notes

Turn one section of a Markdown changelog into Google Play "What's new" text per language and check each against Play's 500-character limit. Bullets become •, emphasis, code and link markup is removed, and a bullet's continuation lines are joined. The files are written in the layout fastlane supply, Gradle Play Publisher or a whatsnew directory reads; nothing is written when a language fails. The result's release_notes is the release_notes argument of play.prepare. Reads and writes local files only.

Annotations: destructive, idempotent, closed world.

ArgumentTypeRequiredDefaultDetails
changelogstringyesnon-empty; Absolute path of the Markdown changelog for language
sectionstring""Heading of the section to use, such as 1.2.0 or Unreleased, matched without brackets, a leading v or what follows a space; empty takes the first section
languagestring"en-US"matching [A-Za-z]{2,3}(-[A-Za-z0-9]{2,8}){0,2}; Google Play language code, such as en-US, de-DE or es-419
translationsarray of objectup to 80 items; Changelogs of other languages with the same section
translations[].languagestringyesmatching [A-Za-z]{2,3}(-[A-Za-z0-9]{2,8}){0,2}; Google Play language code, such as en-US, de-DE or es-419
translations[].changelogstringyesnon-empty; Absolute path of this language's Markdown changelog
directorystring""Absolute path to write the files under: fastlane's metadata/android directory, Gradle Play Publisher's src/main/play, or a whatsnew directory
layoutstring"fastlane"one of fastlane, play-publisher, whatsnew; fastlane: LANGUAGE/changelogs/default.txt, or BUILD.txt with build_number; play-publisher: release-notes/LANGUAGE/default.txt; whatsnew: whatsnew-LANGUAGE
build_numberinteger1 to 2100000000; versionCode for fastlane's per-build file name
truncatebooleanfalseDrop whole lines from the end of a text over the limit instead of failing
dry_runbooleanfalseReturn the texts and findings without writing
tomaccoctl call release.notes '{"changelog":"<changelog>"}'

release.checklist#

Check Android release readiness

Check an Android app's release build before a Play upload, from its build files and manifest without running Gradle: target_sdk against the level Google Play requires (36 for new apps and updates since 31 August 2026), version_code above the previous release, debuggable off, minify on, a release signing config that is not the debug key, and no cleartext HTTP unless allow_cleartext. Each check has a status (pass, fail or unknown), a severity and its evidence; passed is false when an error-severity check fails. artifact reads targetSdk and versionCode from the built APK or AAB instead.

Annotations: read-only, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
pathstringyesnon-empty; Absolute path of the project root, or of its Gradle build
modulestring""Gradle path of the app module, such as :app; the first application module when empty
artifactstring""Absolute path of the built .apk or .aab to read targetSdk and versionCode from
previous_version_codeinteger1 to 2100000000; versionCode of the last release on Google Play
baselinestring""Absolute path of the last released .apk or .aab, instead of previous_version_code
required_target_sdkinteger1 to 100; Target API level to require instead of Google Play's current one
allow_cleartextbooleanfalseCleartext HTTP is intended; report it without failing
tomaccoctl call release.checklist '{"path":"<path>"}'

View this page as Markdown on GitHub