Skip to content

Commit

Permalink
feat: Add lifecycle hooks for publish (#656)
Browse files Browse the repository at this point in the history
This PR adds lifecycle hooks (pre and post) to the publish command.
It runs pre once before publishing runs and post once afterwards (even though several packages might be published).

It also runs in --dry-run mode, to better emulate a real publish.
The environment variable MELOS_PUBLISH_DRY_RUN is introduced so that the user can know whether it is in dry-run mode or not in the scripts.
  • Loading branch information
spydon authored Mar 11, 2024
1 parent 93db45d commit ed826b3
Show file tree
Hide file tree
Showing 16 changed files with 515 additions and 29 deletions.
27 changes: 27 additions & 0 deletions docs/commands/publish.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,30 @@ Note that tags are automatically created as part of `melos version` (unless
`--no-git-tag-version` is specified when running the version command) so this is
usually not required on `melos publish` unless you're doing a manual version and
publish of packages.

## Hooks

Melos supports various command [lifecycle hooks](/configuration/scripts#hooks)
that can be defined in your `melos.yaml`.

For example, if you need to run something such as a build runner automatically
before `melos publish` is run and then remove the generated files after
publishing is done, you can add `pre` and `post` hook scripts to your
`melos.yaml` file:

```yaml
# melos.yaml
# ...
command:
publish:
hooks:
pre: dart pub run build_runner build
post: dart pub run build_runner clean
# ...
```

The pre-hook will run before `melos publish` and the post-hook will run after
`melos publish` is done. It only runs once, even if multiple packages are
published and it also runs when you are doing a `dry-run` publish.
You can detect whether it is a dry-run by checking the `MELOS_PUBLISH_DRY_RUN`
environment variable.
1 change: 1 addition & 0 deletions docs/configuration/scripts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,4 @@ Currently, the following Melos commands support hooks:
- [`bootstrap`](/commands/bootstrap)
- [`clean`](/commands/clean)
- [`version`](/commands/version)
- [`publish`](/commands/publish)
5 changes: 5 additions & 0 deletions docs/environment-variables.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ executing a script (when using `melos exec`).
The path of the parent package of the current package that's currently executing
a script (when using `melos exec`).

### `MELOS_PUBLISH_DRY_RUN`

Whether the current publish is a dry run or not. This is `true` when running
`melos publish --dry-run` and `false` otherwise.

#### What is a 'parent package'

If a package exists in a directory that is also a child of another package, then
Expand Down
31 changes: 25 additions & 6 deletions packages/melos/lib/src/command_configs/command_configs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import '../common/utils.dart';
import '../common/validation.dart';
import 'bootstrap.dart';
import 'clean.dart';
import 'publish.dart';
import 'version.dart';

export 'bootstrap.dart';
Expand All @@ -17,6 +18,7 @@ class CommandConfigs {
this.bootstrap = BootstrapCommandConfigs.empty,
this.clean = CleanCommandConfigs.empty,
this.version = VersionCommandConfigs.empty,
this.publish = PublishCommandConfigs.empty,
});

factory CommandConfigs.fromYaml(
Expand All @@ -42,6 +44,12 @@ class CommandConfigs {
path: 'command',
);

final publishMap = assertKeyIsA<Map<Object?, Object?>?>(
key: 'publish',
map: yaml,
path: 'command',
);

return CommandConfigs(
bootstrap: BootstrapCommandConfigs.fromYaml(
bootstrapMap ?? const {},
Expand All @@ -56,6 +64,11 @@ class CommandConfigs {
workspacePath: workspacePath,
repositoryIsConfigured: repositoryIsConfigured,
),
publish: PublishCommandConfigs.fromYaml(
publishMap ?? const {},
workspacePath: workspacePath,
repositoryIsConfigured: repositoryIsConfigured,
),
);
}

Expand All @@ -64,12 +77,14 @@ class CommandConfigs {
final BootstrapCommandConfigs bootstrap;
final CleanCommandConfigs clean;
final VersionCommandConfigs version;
final PublishCommandConfigs publish;

Map<String, Object?> toJson() {
return {
'bootstrap': bootstrap.toJson(),
'clean': clean.toJson(),
'version': version.toJson(),
'publish': publish.toJson(),
};
}

Expand All @@ -79,14 +94,17 @@ class CommandConfigs {
runtimeType == other.runtimeType &&
other.bootstrap == bootstrap &&
other.clean == clean &&
other.version == version;
other.version == version &&
other.publish == publish;

@override
int get hashCode =>
runtimeType.hashCode ^
bootstrap.hashCode ^
clean.hashCode ^
version.hashCode;
int get hashCode => Object.hash(
runtimeType,
bootstrap,
clean,
version,
publish,
);

@override
String toString() {
Expand All @@ -95,6 +113,7 @@ CommandConfigs(
bootstrap: ${bootstrap.toString().indent(' ')},
clean: ${clean.toString().indent(' ')},
version: ${version.toString().indent(' ')},
publish: ${publish.toString().indent(' ')},
)
''';
}
Expand Down
Loading

0 comments on commit ed826b3

Please sign in to comment.