This file provides guidance to AI agents when working with code in this repository.
Release Toolkit is a fastlane plugin implemented as a Ruby gem (fastlane-plugin-wpmreleasetoolkit) providing actions and helper utilities for release automation of Automattic's mobile apps. It standardizes the release process across multiple products (WordPress, Jetpack, WooCommerce, Day One, Pocket Casts, Tumblr, Studio, …), repositories, and platforms (iOS, Android, macOS).
- Language: Ruby (version in
.ruby-version, minimum infastlane-plugin-wpmreleasetoolkit.gemspec) - Framework: Fastlane plugin
- License: GPLv2
- Main branch:
trunk - Gem version: defined in
lib/fastlane/plugin/wpmreleasetoolkit/version.rb
bundle install # Install dependencies
bundle exec rspec # Run all tests
bundle exec rspec spec/path_spec.rb # Run a single test file
bundle exec rubocop # Run linter
bundle exec rubocop -a # Auto-fix lint issues
bundle exec yard doc # Generate docs, open in browser
bundle exec yard stats --list-undoc # Show undocumented methods
gem build # Build the gem (no arguments — auto-picks the gemspec)
rake new_release # Start a new release (interactive)lib/fastlane/plugin/wpmreleasetoolkit/
├── actions/ # Fastlane actions (entry points)
│ ├── android/ # Android-specific actions
│ ├── common/ # Cross-platform actions
│ ├── configure/ # Project configuration actions
│ └── ios/ # iOS-specific actions
├── helper/ # Business logic modules and classes
│ ├── android/ # Android helpers
│ ├── ios/ # iOS helpers
│ └── metadata/ # Metadata/PO file generation
├── models/ # Data model classes
├── versioning/ # Version management system
│ ├── calculators/ # Version number calculation strategies
│ ├── files/ # Platform-specific version file I/O
│ └── formatters/ # Version string formatting strategies
└── version.rb # Gem version constant
spec/ # RSpec tests (mirrors lib/ structure)
rakelib/ # Rake task helpers
docs/ # Additional documentation
All actions inherit from Fastlane::Action and follow this structure:
module Fastlane
module Actions
class MyAction < Action
def self.run(params)
# Implementation — delegate business logic to helpers
end
def self.available_options
[
FastlaneCore::ConfigItem.new(
key: :param_name,
env_name: 'ENV_VAR_NAME',
description: 'Description',
optional: false,
type: String
),
]
end
def self.description
'One-line description'
end
def self.authors
['Automattic']
end
def self.is_supported?(platform)
true
end
end
end
endKey conventions:
- Actions orchestrate; helpers contain business logic.
- Use
UI.user_error!for validation failures,UI.message/UI.successfor output. - Shell commands go through
Action.sh('command', *args). - Config items support
env_namefor environment variable fallback andverify_blockfor validation.
- Modules (static methods) for stateless utilities:
GitHelper,GlotPressHelper. - Classes for stateful operations:
GithubHelper(wraps Octokit),ConfigureHelper. - Platform-specific helpers live in
helper/android/andhelper/ios/.
Uses a strategy pattern with three layers:
- Calculators compute the next version (semantic, date-based, marketing).
- Formatters convert between strings and
AppVersionobjects. - Files read/write platform-specific version files (
.xcconfig,version.properties).
All have abstract base classes (AbstractVersionCalculator, AbstractVersionFormatter).
Simple data classes in models/: AppVersion, BuildCode, Configuration, FileReference, and Firebase-related models.
- Framework: RSpec (config in
.rspec) - HTTP mocking: WebMock (real HTTP requests are disabled)
- Test data: Fixtures in
spec/test-data/
| Helper | Purpose |
|---|---|
run_described_fastlane_action(params) |
Run the action being described in a test lane |
allow_fastlane_action_sh |
Enable Action.sh in test environment |
expect_shell_command(*cmd, exitstatus:, output:) |
Assert shell command execution |
sawyer_resource_stub(**fields) |
Mock GitHub API (Sawyer) responses |
in_tmp_dir { |tmpdir| ... } |
Execute block in a temporary directory |
with_tmp_file(named:, content:) { |path| ... } |
Execute block with a temporary file |
Configuration is in .rubocop.yml. Key rules:
- Trailing commas in multi-line arrays are required (
consistent_comma) for cleaner diffs. - Hash shorthand syntax is disallowed (
{a:, b:}— use{a: a, b: b}). - Empty methods must use expanded style (multi-line
def ... end). - Unused method arguments are allowed (common in action API contracts).
Style/StringConcatenationis disabled due toPathname#+issues.Style/FetchEnvVaris disabled.- Generous metric limits (e.g., line length 300, method length 150).
- RSpec cops:
ExampleLength,MultipleMemoizedHelpers,MultipleExpectationsare disabled.
Pipeline defined in .buildkite/pipeline.yml:
- Tests: RSpec on macOS agents with Ruby matrix.
- Linters: RuboCop and Danger run on PRs only.
- Gem publishing: Automatic on git tag creation (pushes to RubyGems).
Single workflow (.github/workflows/run-danger.yml) triggers Danger checks on Buildkite for PR events.
Automated PR checks include:
- RuboCop lint (full scan, inline comments, fails on violations).
Gemfile.lockupdate verification.- Version consistency between
version.rbandGemfile.lock. - CHANGELOG.md modification required.
- PR diff size limit (500 lines).
- Label checks (
Do Not Merge). - Reviewer assignment reminder.
- Draft PRs skip some checks.
From .github/PULL_REQUEST_TEMPLATE.md:
- Run
bundle exec rubocop— no violations. - Add unit tests in
spec/. - Run
bundle exec rspec— all tests pass. - Add a CHANGELOG.md entry under the
## Trunksection. - Add a MIGRATION.md entry if there are breaking changes.
The CHANGELOG uses these sections under each version:
### Breaking Changes### New Features### Bug Fixes### Internal Changes
Unreleased changes go under ## Trunk. Empty sections use _None_ as placeholder. Entries reference PR numbers: [#123].
Version bump semantics: Breaking Changes = major, New Features = minor, Bug Fixes/Internal = patch.
rake new_release— interactive task that:- Parses CHANGELOG for pending changes and suggests the next semantic version.
- Creates a
release/<version>branch. - Updates
version.rb,Gemfile.lock, and CHANGELOG. - Commits, pushes, and opens a draft PR.
- After PR merge, create a GitHub Release targeting
trunk. - The GitHub Release creates a git tag, which triggers Buildkite to publish the gem to RubyGems.
Runtime and development dependencies with version constraints are defined in fastlane-plugin-wpmreleasetoolkit.gemspec and Gemfile. Key runtime dependencies include:
- fastlane — plugin framework
- octokit — GitHub API
- git — git operations
- xcodeproj — Xcode project files
- nokogiri — XML parsing
- gettext — i18n/PO files
- google-cloud-storage — GCS uploads
- buildkit — Buildkite API