Skip to content

Commit e3a6159

Browse files
authored
Enhance AGENTS.md with additional project details (#692)
2 parents 87f4213 + f401957 commit e3a6159

2 files changed

Lines changed: 211 additions & 2 deletions

File tree

AGENTS.md

Lines changed: 210 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,213 @@ This file provides guidance to AI agents when working with code in this reposito
44

55
## Overview
66

7-
Release Toolkit is a Ruby gem providing shared tools used in release automation for WordPress mobile apps.
8-
It is a collection of `fastlane` actions and helper utilities that standardize the release process across multiple repositories.
7+
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, DayOne, PocketCats, Tumblr, Studio, …), repositories, and platforms (iOS, Android, macOS).
8+
9+
- **Language**: Ruby (version in `.ruby-version`, minimum in `fastlane-plugin-wpmreleasetoolkit.gemspec`)
10+
- **Framework**: Fastlane plugin
11+
- **License**: GPLv2
12+
- **Main branch**: `trunk`
13+
- **Gem version**: defined in `lib/fastlane/plugin/wpmreleasetoolkit/version.rb`
14+
15+
## Build and Development Commands
16+
17+
```sh
18+
bundle install # Install dependencies
19+
bundle exec rspec # Run all tests
20+
bundle exec rspec spec/path_spec.rb # Run a single test file
21+
bundle exec rubocop # Run linter
22+
bundle exec rubocop -a # Auto-fix lint issues
23+
bundle exec yard doc # Generate docs, open in browser
24+
bundle exec yard stats --list-undoc # Show undocumented methods
25+
rake new_release # Start a new release (interactive)
26+
```
27+
28+
## Project Structure
29+
30+
```
31+
lib/fastlane/plugin/wpmreleasetoolkit/
32+
├── actions/ # Fastlane actions (entry points)
33+
│ ├── android/ # Android-specific actions
34+
│ ├── common/ # Cross-platform actions
35+
│ ├── configure/ # Project configuration actions
36+
│ └── ios/ # iOS-specific actions
37+
├── helper/ # Business logic modules and classes
38+
│ ├── android/ # Android helpers
39+
│ ├── ios/ # iOS helpers
40+
│ └── metadata/ # Metadata/PO file generation
41+
├── models/ # Data model classes
42+
├── versioning/ # Version management system
43+
│ ├── calculators/ # Version number calculation strategies
44+
│ ├── files/ # Platform-specific version file I/O
45+
│ └── formatters/ # Version string formatting strategies
46+
└── version.rb # Gem version constant
47+
spec/ # RSpec tests (mirrors lib/ structure)
48+
rakelib/ # Rake task helpers
49+
docs/ # Additional documentation
50+
```
51+
52+
## Code Patterns
53+
54+
### Actions
55+
56+
All actions inherit from `Fastlane::Action` and follow this structure:
57+
58+
```ruby
59+
module Fastlane
60+
module Actions
61+
class MyAction < Action
62+
def self.run(params)
63+
# Implementation — delegate business logic to helpers
64+
end
65+
66+
def self.available_options
67+
[
68+
FastlaneCore::ConfigItem.new(
69+
key: :param_name,
70+
env_name: 'ENV_VAR_NAME',
71+
description: 'Description',
72+
optional: false,
73+
type: String
74+
),
75+
]
76+
end
77+
78+
def self.description
79+
'One-line description'
80+
end
81+
82+
def self.authors
83+
['Automattic']
84+
end
85+
86+
def self.is_supported?(platform)
87+
true
88+
end
89+
end
90+
end
91+
end
92+
```
93+
94+
Key conventions:
95+
- Actions orchestrate; helpers contain business logic.
96+
- Use `UI.user_error!` for validation failures, `UI.message`/`UI.success` for output.
97+
- Shell commands go through `Action.sh('command', *args)`.
98+
- Config items support `env_name` for environment variable fallback and `verify_block` for validation.
99+
100+
### Helpers
101+
102+
- **Modules** (static methods) for stateless utilities: `GitHelper`, `GlotPressHelper`.
103+
- **Classes** for stateful operations: `GithubHelper` (wraps Octokit), `ConfigureHelper`.
104+
- Platform-specific helpers live in `helper/android/` and `helper/ios/`.
105+
106+
### Versioning System
107+
108+
Uses a strategy pattern with three layers:
109+
- **Calculators** compute the next version (semantic, date-based, marketing).
110+
- **Formatters** convert between strings and `AppVersion` objects.
111+
- **Files** read/write platform-specific version files (`.xcconfig`, `version.properties`).
112+
113+
All have abstract base classes (`AbstractVersionCalculator`, `AbstractVersionFormatter`).
114+
115+
### Models
116+
117+
Simple data classes in `models/`: `AppVersion`, `BuildCode`, `Configuration`, `FileReference`, and Firebase-related models.
118+
119+
## Testing
120+
121+
- **Framework**: RSpec (config in `.rspec`)
122+
- **HTTP mocking**: WebMock (real HTTP requests are disabled)
123+
- **Test data**: Fixtures in `spec/test-data/`
124+
125+
### Custom Test Helpers (defined in `spec/spec_helper.rb`)
126+
127+
| Helper | Purpose |
128+
|--------|---------|
129+
| `run_described_fastlane_action(params)` | Run the action being described in a test lane |
130+
| `allow_fastlane_action_sh` | Enable `Action.sh` in test environment |
131+
| `expect_shell_command(*cmd, exitstatus:, output:)` | Assert shell command execution |
132+
| `sawyer_resource_stub(**fields)` | Mock GitHub API (Sawyer) responses |
133+
| `in_tmp_dir { \|tmpdir\| ... }` | Execute block in a temporary directory |
134+
| `with_tmp_file(named:, content:) { \|path\| ... }` | Execute block with a temporary file |
135+
136+
## Style Guide (RuboCop)
137+
138+
Configuration is in `.rubocop.yml`. Key rules:
139+
140+
- **Trailing commas** in multi-line arrays are required (`consistent_comma`) for cleaner diffs.
141+
- **Hash shorthand syntax** is disallowed (`{a:, b:}` — use `{a: a, b: b}`).
142+
- **Empty methods** must use expanded style (multi-line `def ... end`).
143+
- **Unused method arguments** are allowed (common in action API contracts).
144+
- `Style/StringConcatenation` is disabled due to `Pathname#+` issues.
145+
- `Style/FetchEnvVar` is disabled.
146+
- Generous metric limits (e.g., line length 300, method length 150).
147+
- RSpec cops: `ExampleLength`, `MultipleMemoizedHelpers`, `MultipleExpectations` are disabled.
148+
149+
## CI/CD
150+
151+
### Buildkite (primary CI)
152+
153+
Pipeline defined in `.buildkite/pipeline.yml`:
154+
- **Tests**: RSpec on macOS agents with Ruby matrix.
155+
- **Linters**: RuboCop and Danger run on PRs only.
156+
- **Gem publishing**: Automatic on git tag creation (pushes to RubyGems).
157+
158+
### GitHub Actions
159+
160+
Single workflow (`.github/workflows/run-danger.yml`) triggers Danger checks on Buildkite for PR events.
161+
162+
### Danger Checks (Dangerfile)
163+
164+
Automated PR checks include:
165+
- RuboCop lint (full scan, inline comments, fails on violations).
166+
- `Gemfile.lock` update verification.
167+
- Version consistency between `version.rb` and `Gemfile.lock`.
168+
- CHANGELOG.md modification required.
169+
- PR diff size limit (500 lines).
170+
- Label checks (`Do Not Merge`).
171+
- Reviewer assignment reminder.
172+
- Draft PRs skip some checks.
173+
174+
## Pull Request Checklist
175+
176+
From `.github/PULL_REQUEST_TEMPLATE.md`:
177+
1. Run `bundle exec rubocop` — no violations.
178+
2. Add unit tests in `spec/`.
179+
3. Run `bundle exec rspec` — all tests pass.
180+
4. Add a CHANGELOG.md entry under the `## Trunk` section.
181+
5. Add a MIGRATION.md entry if there are breaking changes.
182+
183+
## CHANGELOG Conventions
184+
185+
The CHANGELOG uses these sections under each version:
186+
- `### Breaking Changes`
187+
- `### New Features`
188+
- `### Bug Fixes`
189+
- `### Internal Changes`
190+
191+
Unreleased changes go under `## Trunk`. Empty sections use `_None_` as placeholder. Entries reference PR numbers: `[#123]`.
192+
193+
Version bump semantics: Breaking Changes = major, New Features = minor, Bug Fixes/Internal = patch.
194+
195+
## Release Process
196+
197+
1. `rake new_release` — interactive task that:
198+
- Parses CHANGELOG for pending changes and suggests the next semantic version.
199+
- Creates a `release/<version>` branch.
200+
- Updates `version.rb`, `Gemfile.lock`, and CHANGELOG.
201+
- Commits, pushes, and opens a draft PR.
202+
2. After PR merge, create a GitHub Release targeting `trunk`.
203+
3. The GitHub Release creates a git tag, which triggers Buildkite to publish the gem to RubyGems.
204+
205+
## Key Dependencies
206+
207+
Runtime and development dependencies with version constraints are defined in `fastlane-plugin-wpmreleasetoolkit.gemspec` and `Gemfile`. Key runtime dependencies include:
208+
209+
- **fastlane** — plugin framework
210+
- **octokit** — GitHub API
211+
- **git** — git operations
212+
- **xcodeproj** — Xcode project files
213+
- **nokogiri** — XML parsing
214+
- **gettext** — i18n/PO files
215+
- **google-cloud-storage** — GCS uploads
216+
- **buildkit** — Buildkite API

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ _None_
1818

1919
### Internal Changes
2020

21+
- Enhance `AGENTS.md` with comprehensive project guidance for AI agents. [#692]
2122
- Bumped `faraday` to address security vulnerability. [#689]
2223
- Bumped `nokogiri` to address security vulnerability. [#693]
2324

0 commit comments

Comments
 (0)