Skip to content

Update & refactor, support for maintainer mapping #20

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

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
source/*
data/*
.env
14 changes: 12 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
{
"deno.enable": true
}
"deno.enable": true,
"deno.lint": true,
"deno.unstable": false,
"deno.config": "./deno.json",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": "always"
},
"typescript.tsdk": "deno",
"typescript.enable": false,
"javascript.validate.enable": false
}
213 changes: 174 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,68 +1,203 @@
# Project Migrator

### Requirements
A tool for migrating LaunchDarkly projects, including flags, segments, and environments.

- You must have [Deno](https://deno.land/) installed. If you use Homebrew, run `brew install deno`.
## Project Structure

```
project-migrator-script/
├── src/ # Source code
│ ├── scripts/ # Main migration scripts
│ ├── utils/ # Utility functions
│ └── types/ # TypeScript type definitions
├── config/ # Configuration files
├── data/ # Data directory
│ ├── source/ # Downloaded source project data
│ └── mappings/ # Mapping files (e.g., maintainer IDs)
└── .vscode/ # VS Code settings
```

### Considerations
## Prerequisites

- These scripts, `migrate.ts` and `source.ts`, are provided strictly as-is. LaunchDarkly Support cannot help run this.
- [Deno](https://deno.land/) installed
- If you use Homebrew: `brew install deno`
- LaunchDarkly API key with appropriate permissions

### Known issues
## Deno Configuration

- Importing LD API TypeScript types causes an import error, so they are commented out
in various spots.
- Types in general are very loose, which Deno is not happy about. The scripts run as
JavaScript overall instead of validating the TypeScript first.
- Due to the current API configuration, you cannot have more than 20 environments in a single project.
- Due to considerations around many API requests at once, monitor 400 errors for flag configurations that may not be up to date.
The project uses Deno's task runner to simplify command execution. Tasks are defined in `config/deno.json` and can be run using the `deno task` command.

## Things you Should Consider when migrating flags?
### Setting Up Deno Tasks

- What can you scope down? Do all the flags need to moved over or can we use this as a way to clean up the environment?
- Do all my environments need to go? or maybe just a few?
- Am I able to stop edits in the destination project? This script does not keep them in sync, so if changes need to be made they should be prior
- Who is going to run it and how? The calls can take a while, with rate limits, so should I run it on an EC2 or the like?
- If I have thousands or even hundreds of updates: what is critical, how will I verify the changes are correct?
1. **Install Deno** (if not already installed):
```bash
# macOS
brew install deno

# Windows (PowerShell)
iwr https://deno.land/install.ps1 -useb | iex

# Linux
curl -fsSL https://deno.land/x/install/install.sh | sh
```

2. **Verify Installation**:
```bash
deno --version
```

## Instructions for use
3. **Configure VS Code** (optional but recommended):
- Install the "Deno" extension from the VS Code marketplace
- The project includes `.vscode/settings.json` with recommended Deno settings

1. Sourcing data
4. **Project Configuration**:
- The project uses `config/deno.json` for task definitions
- `config/import_map.json` manages module imports
- These files are already configured in the project

First, export your source data. The `source.ts` script writes the data to a newly created
`source/project/<source-project-key>` directory.
### Available Tasks

Here's how to export your source data:
The following tasks are configured in `config/deno.json`:

```json
{
"tasks": {
"start": "deno run --allow-net --allow-read --allow-write src/scripts/source.ts",
"update-maintainers": "deno run --allow-read --allow-write src/scripts/update_maintainers.ts",
"migrate": "deno run --allow-net --allow-read --allow-write src/scripts/migrate.ts"
}
}
```
deno run --allow-env --allow-read --allow-net --allow-write source.ts -p <SOURCE PROJECT KEY> -k <SOURCE LD API KEY>

Each task includes the necessary permissions for file and network access.

## Deno Tasks

The project includes predefined Deno tasks for easier execution. You can run these tasks using the `deno task` command:

```bash
# Download source project data
deno task start -p SOURCE_PROJECT_KEY -k API_KEY

# Update maintainer IDs
deno task update-maintainers -p SOURCE_PROJECT_KEY -m data/mappings/maintainer_mapping.json

# Migrate project
deno task migrate -p SOURCE_PROJECT_KEY -d DESTINATION_PROJECT_KEY -k API_KEY
```

2. Migrating data
### Task Descriptions

1. **start**: Downloads all project data (flags, segments, environments) from the source project
- Requires network access for API calls
- Requires file system access to save downloaded data
- Creates directory structure in `data/source/project/`

2. **update-maintainers**: Updates maintainer IDs in local flag files
- Requires file system access to read and write flag files
- Uses mapping file from `data/mappings/maintainer_mapping.json`

3. **migrate**: Creates a new project with all components
- Requires network access for API calls
- Requires file system access to read source data
- Creates new project with all flags, segments, and environments

### Task Permissions

Each task includes the necessary permissions:
- `--allow-net`: Required for API calls to LaunchDarkly
- `--allow-read`: Required for reading local files
- `--allow-write`: Required for writing downloaded data

These permissions are automatically included in the task definitions, so you don't need to specify them manually.

## Quick Start

Then, migrate the source data to the destination project. The `migrate.ts` script reads the source data out of the previously created `source/project/<source-project-key>` directory. Then it uses the
`DESTINATION PROJECT` as the project key, and updates the destination project using a series of `POST`s and `PATCH`s.
1. **Download Source Project Data**
```bash
deno run --allow-net --allow-read --allow-write src/scripts/source.ts -p SOURCE_PROJECT_KEY -k API_KEY
```

Here's how to migrate the source data to your destination project:
2. **(Optional) Update Maintainer IDs**
```bash
# 1. Create mapping file in data/mappings/maintainer_mapping.json
# 2. Run update script
deno run --allow-read --allow-write src/scripts/update_maintainers.ts -p SOURCE_PROJECT_KEY -m data/mappings/maintainer_mapping.json
```

3. **Migrate Project**
```bash
deno run --allow-net --allow-read --allow-write src/scripts/migrate.ts -p SOURCE_PROJECT_KEY -d DESTINATION_PROJECT_KEY -k API_KEY
```

## Detailed Usage

### 1. Download Source Project Data

Downloads all project data to `data/source/project/SOURCE_PROJECT_KEY/`:
```bash
deno run --allow-net --allow-read --allow-write src/scripts/source.ts -p SOURCE_PROJECT_KEY -k API_KEY
```

### 2. Update Maintainer IDs (Optional)

Create a mapping file at `data/mappings/maintainer_mapping.json`:
```json
{
"old-maintainer-id-1": "new-maintainer-id-1",
"old-maintainer-id-2": "new-maintainer-id-2"
}
```
deno run --allow-env --allow-read --allow-net --allow-write migrate.ts -p <SOURCE PROJECT KEY> -k <DESTINATION LD API KEY> -d <DESTINATION PROJECT KEY>

Update maintainer IDs in local files:
```bash
deno run --allow-read --allow-write src/scripts/update_maintainers.ts -p SOURCE_PROJECT_KEY -m data/mappings/maintainer_mapping.json
```

**Important note** The script currently doesn't support merging two already existing projects - make sure the destination project doesn't exist before executing the `migrate.ts` script. If you have already created the destination project manually, delete the project before proceeding.
### 3. Migrate Project

Creates a new project with all components:
```bash
deno run --allow-net --allow-read --allow-write src/scripts/migrate.ts -p SOURCE_PROJECT_KEY -d DESTINATION_PROJECT_KEY -k API_KEY
```

## Command Line Arguments

### source.ts
- `-p, --projKey`: Source project key
- `-k, --apikey`: LaunchDarkly API key
- `-u, --domain`: (Optional) LaunchDarkly domain, defaults to "app.launchdarkly.com"

### update_maintainers.ts
- `-p, --projKey`: Project key
- `-m, --mappingFile`: Path to the maintainer ID mapping file

### Resources migrated by the script
* Environments
* Flags
* Flag variations
* Flag prerequisites
* Flag individual targets
* Flag attribute-based targeting rules
* Standard User Segments (no Big Segments)
### migrate.ts
- `-p, --projKeySource`: Source project key
- `-d, --projKeyDest`: Destination project key
- `-k, --apikey`: LaunchDarkly API key
- `-u, --domain`: (Optional) LaunchDarkly domain, defaults to "app.launchdarkly.com"

### Pointing to a different instance
## Important Notes

Pass in the `-u` argument with the domain of the other instance. By default, these scripts apply to your projects on `app.launchdarkly.com`.
- The script preserves all original maintainer IDs by default
- Use update_maintainers.ts only if you need to change maintainer IDs
- The update_maintainers.ts script only modifies local files
- Test the migration in a non-production environment first
- The destination project must not exist before migration
- Maximum 20 environments per project
- Monitor for 400 errors in flag configurations

## Known Issues

- TypeScript types are loose due to API client limitations
- Importing LaunchDarkly API TypeScript types causes import errors
- Rate limiting may affect flag configuration updates

## Things you Should Consider when migrating flags?

- What can you scope down? Do all the flags need to moved over or can we use this as a way to clean up the environment?
- Do all my environments need to go? or maybe just a few?
- Am I able to stop edits in the destination project? This script does not keep them in sync, so if changes need to be made they should be prior
- Who is going to run it and how? The calls can take a while, with rate limits, so should I run it on an EC2 or the like?
- If I have thousands or even hundreds of updates: what is critical, how will I verify the changes are correct?
6 changes: 6 additions & 0 deletions config/import_map.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"imports": {
"yargs": "https://deno.land/x/[email protected]/deno.ts",
"std/": "https://deno.land/[email protected]/"
}
}
28 changes: 28 additions & 0 deletions config/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"compilerOptions": {
"allowJs": true,
"lib": [
"esnext",
"dom"
],
"strict": true,
"module": "esnext",
"target": "esnext",
"moduleResolution": "node",
"allowImportingTsExtensions": true,
"noEmit": true,
"isolatedModules": true,
"esModuleInterop": true,
"skipLibCheck": true,
"types": [
"deno"
]
},
"include": [
"**/*.ts",
"deno.d.ts"
],
"exclude": [
"node_modules"
]
}
16 changes: 16 additions & 0 deletions deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"lib": [
"deno.window",
"dom",
"esnext"
],
"strict": true
},
"importMap": "./config/import_map.json",
"tasks": {
"start": "deno run --allow-net --allow-read --allow-write src/scripts/source.ts",
"update-maintainers": "deno run --allow-read --allow-write src/scripts/update_maintainers.ts",
"migrate": "deno run --allow-net --allow-read --allow-write src/scripts/migrate.ts"
}
}
Loading