Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@ packages/*/build
packages/eas-cli/dist
packages/eas-cli/tmp
scripts/build
dist
dist_*

# TypeScript
**/*.tsbuildinfo

# Code editors
.idea
.history
.vscode
*.swp
*.swo

# macOS
.DS_Store
Expand Down
6 changes: 6 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# AGENTS.md

When working with this repository follow instructions from CLAUDE.md.

- [./CLAUDE.md](./CLAUDE.md)

187 changes: 183 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Monorepo Structure

This is a **Lerna-based monorepo** with four packages:
This is a **Lerna-based monorepo** containing the EAS CLI and all supporting build libraries.

### CLI & Configuration Packages

1. **[packages/eas-cli](./packages/eas-cli/CLAUDE.md)** - The main CLI tool (published as `eas-cli`)
- 95+ commands organized by domain (build, submit, update, channel, credentials, etc.)
Expand All @@ -19,12 +21,60 @@ This is a **Lerna-based monorepo** with four packages:
3. **[packages/eas-build-cache-provider](./packages/eas-build-cache-provider/CLAUDE.md)** - Build cache plugin (published as `eas-build-cache-provider`)
- Optimizes build caching for Expo CLI

4. **[packages/worker](./packages/worker/CLAUDE.md)** - Turtle Worker service (private, not published)
### Build Execution Packages

4. **[packages/eas-build-job](./packages/eas-build-job)** - Build job definitions (published as `@expo/eas-build-job`)
- Defines all data structures for build operations (Job, BuildPhase, BuildMode, Platform, Workflow)
- Provides type definitions and validation schemas (Zod, Joi)
- Contains BuildPhase enum that defines the traditional build pipeline stages
- Key exports: `Job`, `BuildPhase`, `BuildMode`, `BuildTrigger`, `Workflow`, `ArchiveSource`
- **Foundation that all other build packages depend on**

5. **[packages/build-tools](./packages/build-tools)** - Build execution engine (published as `@expo/build-tools`)
- Orchestrates all build operations through `BuildContext<T extends Job>`
- Contains platform-specific builders: `androidBuilder()`, `iosBuilder()`, `runCustomBuildAsync()`
- Manages build phases, artifact uploading, caching, credentials
- Provides functions for custom builds
- Integrates with GraphQL API

6. **[packages/steps](./packages/steps)** - Custom build workflow engine (published as `@expo/steps`, ESM module)
- Framework for defining and executing custom build steps
- Key abstractions:
- `BuildWorkflow`: Orchestrates sequential step execution
- `BuildStep`: Individual executable unit with inputs/outputs
- `BuildStepGlobalContext`: Manages shared state and interpolation
- `BuildStepContext`: Per-step execution context
- Supports conditional execution with `if` expressions (using jsep)
- Template interpolation: `${{ steps.step-id.outputs.outputName }}`
- Parses build configs from YAML/JSON

7. **[packages/local-build-plugin](./packages/local-build-plugin)** - Local build execution (published as `eas-cli-local-build-plugin`)
- Allows running EAS builds locally on developer machines
- Entry point: `packages/local-build-plugin/src/main.ts`
- Sets `EAS_BUILD_RUNNER=local-build-plugin` environment variable
- Reuses all build-tools logic for consistency with cloud builds

8. **[packages/worker](./packages/worker/CLAUDE.md)** - Turtle Worker service (private, not published)
- Runs on EAS build VMs/pods
- WebSocket server for communication with Turtle Launcher
- Wraps `@expo/build-tools` to execute actual React Native builds

> **Note**: Each package has its own CLAUDE.md with package-specific guidance. Click the links above to view them.
### Supporting Packages

9. **[packages/logger](./packages/logger)** - Bunyan-based structured logging (published as `@expo/logger`)
- Used by all build packages

10. **[packages/downloader](./packages/downloader)** - HTTP file downloading with retry logic (published as `@expo/downloader`)

11. **[packages/turtle-spawn](./packages/turtle-spawn)** - Child process spawning with error handling (published as `@expo/turtle-spawn`)

12. **[packages/template-file](./packages/template-file)** - Lodash-based template string interpolation (published as `@expo/template-file`)

13. **[packages/create-eas-build-function](./packages/create-eas-build-function)** - CLI scaffolding tool for custom build functions (published as `create-eas-build-function`)

14. **[packages/expo-cocoapods-proxy](./packages/expo-cocoapods-proxy)** - Ruby gem for CocoaPods proxy (published as `expo-cocoapods-proxy` gem)

> **Note**: Some packages have their own CLAUDE.md with package-specific guidance. Click the links above to view them.

## Common Development Commands

Expand Down Expand Up @@ -52,6 +102,8 @@ yarn test --watch # Run tests in watch mode
cd packages/eas-cli && yarn test
cd packages/eas-json && yarn test
cd packages/worker && yarn test
cd packages/build-tools && yarn jest-unit
cd packages/steps && yarn test
```

### Type Checking & Linting
Expand All @@ -73,19 +125,107 @@ alias easd="$(pwd)/packages/eas-cli/bin/run"
easd build --help
```

### Local Build Testing

Set up environment variables for testing local builds:

```bash
export EAS_LOCAL_BUILD_PLUGIN_PATH=$HOME/expo/eas-cli/bin/eas-cli-local-build-plugin
export EAS_LOCAL_BUILD_WORKINGDIR=$HOME/expo/eas-build-workingdir
export EAS_LOCAL_BUILD_SKIP_CLEANUP=1
export EAS_LOCAL_BUILD_ARTIFACTS_DIR=$HOME/expo/eas-build-workingdir/results

# Then run build with --local flag in eas-cli
eas build --local
```

## Build System

Each package has independent TypeScript compilation:
- `eas-cli`: `src/` → `build/`
- `eas-json`: `src/` → `build/`
- `eas-build-cache-provider`: `src/` → `build/`
- `worker`: `src/` → `dist/`
- `build-tools`: `src/` → `dist/`
- `eas-build-job`: `src/` → `dist/`
- `steps`: `src/` → `dist_esm/` and `dist_commonjs/`
- `local-build-plugin`: `src/` → `dist/`
- Other packages: `src/` → `dist/`

TypeScript configs:
- `tsconfig.json` - Base configuration (extends @tsconfig/node18)
- `tsconfig.build.json` - Production builds
- `tsconfig.allowUnused.json` - Development with relaxed rules

## Key Architectural Patterns

### Build Phases

Most traditional build operations are wrapped in phases for tracking:

```typescript
await ctx.runBuildPhase(BuildPhase.INSTALL_DEPENDENCIES, async () => {
// Phase logic here
});
```

Phases can be marked as skipped, warning, or failed for granular reporting.

### Context Objects

- **BuildContext** (`build-tools`): For traditional builds, wraps Job, manages phases/artifacts/caching
- **CustomBuildContext** (`build-tools`): Implements `ExternalBuildContextProvider`, bridges BuildContext to steps framework, used in custom builds and generic jobs
- **BuildStepGlobalContext** (`steps`): Manages step outputs, interpolation, shared state
- **BuildStepContext** (`steps`): Per-step context with working directory and logger

### Custom Build Steps

Steps are defined with:

- `id`: Unique identifier
- `name`: Display name
- `run`: Command or function reference
- `if`: Optional condition (`${{ always() }}`, `${{ success() }}`, etc.)
- `inputs`: Key-value inputs to the step
- `outputs`: Named outputs accessible to later steps

Built-in step functions are in `packages/build-tools/src/steps/functions/`

### Conditional Execution

Uses jsep for expression evaluation:

```yaml
if: ${{ steps.previous_step.outputs.success == 'true' && env.ENVIRONMENT == 'production' }}
```

### Artifact Management

Artifacts tracked as `ArtifactToUpload`:

- Managed artifacts (APK, IPA, AAB) with specific handling
- Generic artifacts for any file
- Upload via `ctx.uploadArtifact()` or `upload-artifact` step

## Package Interdependencies

```
eas-cli → @expo/eas-json
→ @expo/build-tools → @expo/eas-build-job
→ @expo/steps → @expo/eas-build-job
→ @expo/logger
→ @expo/turtle-spawn
→ @expo/downloader
→ @expo/template-file

local-build-plugin → @expo/build-tools → @expo/eas-build-job
→ @expo/turtle-spawn

worker → @expo/build-tools
```

Most packages depend on `@expo/eas-build-job` as the source of truth for types.

## Testing Architecture

- **Framework**: Jest with multi-project configuration
Expand All @@ -103,6 +243,31 @@ yarn test <path-to-test-file>
yarn test packages/eas-cli/src/project/__tests__/projectUtils-test.ts
```

## Common Development Scenarios

### Adding a Built-in Step Function

1. Create file in `packages/build-tools/src/steps/functions/yourFunction.ts`
2. Export `createYourFunctionBuildFunction()` following existing patterns
3. Add to `getEasFunctions()` in `packages/build-tools/src/steps/functions/easFunctions.ts`
4. Function receives `BuildStepContext` and input/output maps

### Adding Error Detection

1. Add pattern detection in `packages/build-tools/src/buildErrors/detectError.ts`
2. Implement resolver for better error messages
3. Helps users understand and fix build failures

### Working with Platform-Specific Builders

- **Android builder** (`packages/build-tools/src/builders/android.ts`): Gradle-based, handles APK/AAB generation, also see `functionGroups/build.ts`
- **iOS builder** (`packages/build-tools/src/builders/ios.ts`): Fastlane/Xcode-based, handles IPA generation, also see `functionGroups/build.ts`
- Both use `runBuilderWithHooksAsync()` which runs build result hooks (on-success, on-error, on-complete) from package.json

### Introducing Breaking Changes to Job API (@expo/eas-build-job)

If you want to introduce breaking changes to the `@expo/eas-build-job` package, contact one of the CODEOWNERS to coordinate changes with EAS build servers and GraphQL API. Describe what changes you want to make and why. After everything is deployed to production, you can introduce a PR that relies on the new implementation.

## Environment Variables

```bash
Expand Down Expand Up @@ -134,6 +299,12 @@ Log.warn('Warning message');
Log.error('Error message');
```

### Commit Messages
- When possible, prepend commit messages with `[PACKAGE-BEING-CHANGED]`, e.g. `[steps] Add new step function`
- Do not use prefixes like `chore:` and `feat:`
- Commit messages should be concise. Only complex changes should be longer than one line
- Commit changes in logical groups

## Release Process

1. Update `CHANGELOG.md` in the appropriate package
Expand All @@ -144,8 +315,16 @@ Log.error('Error message');
3. GitHub Actions workflow handles release automation
4. Notifications sent to Slack #eas-cli channel

## Licensing

This repository contains packages under different licenses:
- **MIT License**: `eas-cli`, `@expo/eas-json`, `@expo/eas-build-job`, `eas-build-cache-provider`
- **BUSL-1.1 (Business Source License)**: `@expo/build-tools`, `@expo/steps`, `@expo/logger`, `@expo/downloader`, `@expo/turtle-spawn`, `@expo/template-file`, `eas-cli-local-build-plugin`

See `LICENSE` (MIT) and `LICENSE-BUSL` (BUSL-1.1) for details.

## Important Notes

- **Node Version**: Requires Node.js >= 18.0.0 (managed via Volta)
- **Package Manager**: Uses Yarn 1.22.21
- **Compilation Target**: CommonJS with Node resolution
- **Compilation Target**: CommonJS with Node resolution (except `@expo/steps` which is ESM)
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ For development against staging API:

## Working on local builds (`eas build --local`)

See https://github.com/expo/eas-build/blob/main/DEVELOPMENT.md for how to set up your environment when making changes to [`eas-cli-local-build-plugin`](https://github.com/expo/eas-build/tree/main/packages/local-build-plugin) and/or [`build-tools`](https://github.com/expo/eas-build/tree/main/packages/build-tools).
See [`CLAUDE.md`](./CLAUDE.md) for how to set up your environment when making changes to [`eas-cli-local-build-plugin`](./packages/local-build-plugin) and/or [`build-tools`](./packages/build-tools).

## Testing

Expand Down
100 changes: 100 additions & 0 deletions LICENSE-BUSL
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
Business Source License 1.1

Parameters

Licensor: 650 Industries, Inc.
Licensed Work: EAS Build
The Licensed Work is (c) 2021 650 Industries, Inc.
Additional Use Grant: You may make use of the Licensed Work, provided that you do
not use the Licensed Work for commercial offerings such as
a CI/CD service or application build service that allows
third parties (other than your employees and contractors)
to access the functionality of and directly benefit from the
functionality of the Licensed Work.

Change Date: 2028-04-01

Change License: MIT

For information about alternative licensing arrangements for the Software,
please visit: https://expo.dev/pricing/

Notice

The Business Source License (this document, or the "License") is not an Open
Source license. However, the Licensed Work will eventually be made available
under an Open Source License, as stated in this License.

License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
"Business Source License" is a trademark of MariaDB Corporation Ab.

-----------------------------------------------------------------------------

Business Source License 1.1

Terms

The Licensor hereby grants you the right to copy, modify, create derivative
works, redistribute, and make non-production use of the Licensed Work. The
Licensor may make an Additional Use Grant, above, permitting limited
production use.

Effective on the Change Date, or the fourth anniversary of the first publicly
available distribution of a specific version of the Licensed Work under this
License, whichever comes first, the Licensor hereby grants you rights under
the terms of the Change License, and the rights granted in the paragraph
above terminate.

If your use of the Licensed Work does not comply with the requirements
currently in effect as described in this License, you must purchase a
commercial license from the Licensor, its affiliated entities, or authorized
resellers, or you must refrain from using the Licensed Work.

All copies of the original and modified Licensed Work, and derivative works
of the Licensed Work, are subject to this License. This License applies
separately for each version of the Licensed Work and the Change Date may vary
for each version of the Licensed Work released by Licensor.

You must conspicuously display this License on each original or modified copy
of the Licensed Work. If you receive the Licensed Work in original or
modified form from a third party, the terms and conditions set forth in this
License apply to your use of that work.

Any use of the Licensed Work in violation of this License will automatically
terminate your rights under this License for the current and all other
versions of the Licensed Work.

This License does not grant you any right in any trademark or logo of
Licensor or its affiliates (provided that you may use a trademark or logo of
Licensor as expressly required by this License).

TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
TITLE.

MariaDB hereby grants you permission to use this License’s text to license
your works, and to refer to it using the trademark "Business Source License",
as long as you comply with the Covenants of Licensor below.

Covenants of Licensor

In consideration of the right to use this License’s text and the "Business
Source License" name and trademark, Licensor covenants to MariaDB, and to all
other recipients of the licensed work to be provided by Licensor:

1. To specify as the Change License the GPL Version 2.0 or any later version,
or a license that is compatible with GPL Version 2.0 or a later version,
where "compatible" means that software provided under the Change License can
be included in a program with software provided under GPL Version 2.0 or a
later version. Licensor may specify additional Change Licenses without
limitation.

2. To either: (a) specify an additional grant of rights to use that does not
impose any additional restriction on the right granted in this License, as
the Additional Use Grant; or (b) insert the text "None".

3. To specify a Change Date.

4. Not to modify this License in any other way.
Loading