Skip to content
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

Build packages with tsup #2120

Merged
merged 18 commits into from
Feb 22, 2024
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 11 additions & 79 deletions .github/workflows/build-lint-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,43 +37,14 @@ jobs:
id: workspace-package-names
run: |
{
echo "test-workspace-package-names=$(yarn workspaces filter --include 'packages/*' --exclude 'packages/examples' --json)"
echo "e2e-workspace-package-names=$(yarn workspaces filter --include 'packages/examples/packages/**' --exclude 'packages/examples/packages/invoke-snap' --json)"
echo "all-workspace-package-names=$(yarn workspaces filter --include '{.,packages/**}' --exclude 'packages/snaps-cli/test/snap' --json)"
echo "test-workspace-package-names=$(yarn workspaces filter list --include 'packages/*' --exclude 'packages/examples' --json)"
echo "e2e-workspace-package-names=$(yarn workspaces filter list --include 'packages/examples/packages/**' --exclude 'packages/examples/packages/invoke-snap' --json)"
echo "all-workspace-package-names=$(yarn workspaces filter list --include '{.,packages/**}' --exclude 'packages/snaps-cli/test/snap' --json)"
} >> "$GITHUB_OUTPUT"
shell: bash

build-source:
name: Build source
runs-on: ubuntu-latest
needs: prepare
steps:
- uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
cache: yarn
- run: yarn --immutable --immutable-cache
- name: Build source
run: yarn build:source
- name: Cache build files
uses: actions/cache@v3
with:
path: |
packages/*/dist/esm
packages/*/dist/cjs
key: build-source-${{ runner.os }}-${{ github.sha }}
- name: Require clean working directory
shell: bash
run: |
if ! git diff --exit-code; then
echo "Working tree dirty at end of job"
exit 1
fi

build-types:
name: Build types
build:
name: Build
runs-on: ubuntu-latest
needs: prepare
steps:
Expand All @@ -84,14 +55,16 @@ jobs:
node-version-file: '.nvmrc'
cache: yarn
- run: yarn --immutable --immutable-cache
- name: Build
run: yarn build:ci
- name: Build types
run: yarn build:types
- name: Cache build files
uses: actions/cache@v3
with:
path: |
packages/*/dist/types
key: build-types-${{ runner.os }}-${{ github.sha }}
packages/*/dist
key: build-source-${{ runner.os }}-${{ github.sha }}
- name: Require clean working directory
shell: bash
run: |
Expand All @@ -100,38 +73,6 @@ jobs:
exit 1
fi

post-build:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed all post-tsc scripts for simplicity.

name: Post-build
runs-on: ubuntu-latest
needs:
- build-source
- build-types
steps:
- uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
cache: yarn
- run: yarn --immutable --immutable-cache
- name: Restore build files
uses: actions/cache@v3
with:
path: |
packages/*/dist/esm
packages/*/dist/cjs
key: build-source-${{ runner.os }}-${{ github.sha }}
fail-on-cache-miss: true
- name: Restore types files
uses: actions/cache@v3
with:
path: |
packages/*/dist/types
key: build-types-${{ runner.os }}-${{ github.sha }}
fail-on-cache-miss: true
- name: Post-build
run: yarn build:post-tsc:ci

build-simulator:
name: Build "@metamask/snaps-simulator"
runs-on: ubuntu-latest
Expand Down Expand Up @@ -318,8 +259,7 @@ jobs:
runs-on: ubuntu-latest
needs:
- prepare
- build-source
- build-types
- build
strategy:
fail-fast: false
matrix:
Expand All @@ -343,17 +283,9 @@ jobs:
uses: actions/cache@v3
with:
path: |
packages/*/dist/esm
packages/*/dist/cjs
packages/*/dist
key: build-source-${{ runner.os }}-${{ github.sha }}
fail-on-cache-miss: true
- name: Restore types files
uses: actions/cache@v3
with:
path: |
packages/*/dist/types
key: build-types-${{ runner.os }}-${{ github.sha }}
fail-on-cache-miss: true
- run: yarn --immutable --immutable-cache
- name: Build snap
run: yarn workspace ${{ matrix.package-name }} run build
Expand Down
184 changes: 156 additions & 28 deletions .yarn/plugins/local/plugin-workspaces-filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ module.exports = {
const { Command, Option, UsageError } = require('clipanion');
const { isString, isBoolean } = require('typanion');

class FilterCommand extends BaseCommand {
static paths = [['workspaces', 'filter']];
class FilterListCommand extends BaseCommand {
static paths = [['workspaces', 'filter', 'list']];

static usage = Command.Usage({
description: 'Filter workspaces',
Expand All @@ -18,11 +18,11 @@ module.exports = {
examples: [
[
`List workspaces based on a glob pattern`,
`yarn workspaces filter --include "packages/*"`,
`yarn workspaces filter list --include "packages/*"`,
],
[
'Exclude workspaces based on a glob pattern',
`yarn workspaces filter --exclude "packages/*/foo"`,
`yarn workspaces filter list --exclude "packages/*/foo"`,
],
],
});
Expand All @@ -42,6 +42,34 @@ module.exports = {
validator: isBoolean,
});

/**
* List the names of the workspaces. If `--json` is set, the names will be
* printed as a JSON array.
*
* @param {Workspace[]} workspaces
* @param {Configuration} configuration
* @returns {Promise<number>}
*/
async list(workspaces, configuration) {
const report = await StreamReport.start(
{
configuration,
json: this.json,
stdout: this.context.stdout,
},
async (report) => {
for (const workspace of workspaces) {
report.reportInfo(null, workspace.relativeCwd);
}

const result = workspaces.map((workspace) => workspace.manifest.raw.name);
report.reportJson(result);
},
);

return report.exitCode();
}

async execute() {
// Note: We have to import `minimatch` here, because Yarn will always
// load the plugin, even if the command is not used, and `minimatch`
Expand All @@ -61,37 +89,137 @@ module.exports = {
);
}

const report = await StreamReport.start(
{
configuration,
json: this.json,
stdout: this.context.stdout,
},
async (report) => {
const filteredWorkspaces = workspaces.filter((workspace) => {
return (
(!this.include ||
minimatch(workspace.relativeCwd, this.include)) &&
(!this.exclude ||
!minimatch(workspace.relativeCwd, this.exclude))
);
});

for (const workspace of filteredWorkspaces) {
report.reportInfo(null, workspace.relativeCwd);
}
const filteredWorkspaces = workspaces.filter((workspace) => {
return (
(!this.include ||
minimatch(workspace.relativeCwd, this.include)) &&
(!this.exclude ||
!minimatch(workspace.relativeCwd, this.exclude))
);
});

const result = filteredWorkspaces.map((workspace) => workspace.manifest.raw.name);
report.reportJson(result);
},
return await this.list(filteredWorkspaces, configuration);
}
}

class FilterRunCommand extends BaseCommand {
static paths = [['workspaces', 'filter']];

static usage = Command.Usage({
description: 'Filter workspaces',
details: `
This command will run a command in workspaces based on the given
criteria. It's like \`yarn workspaces foreach\` but on steroids.
`,
examples: [
[
`List workspaces based on a glob pattern`,
`yarn workspaces filter --include "packages/*" run build`,
],
[
'Exclude workspaces based on a glob pattern',
`yarn workspaces filter --exclude "packages/*/foo" run build`,
],
],
});

commandName = Option.String({
required: true,
description: `The name of the command to run`,
validator: isString,
});

args = Option.Proxy({
required: false,
});

parallel = Option.Boolean(`--parallel`, {
default: false,
description: `Run the commands in parallel`,
validator: isBoolean,
});

topological = Option.Boolean(`--topological`, false, {
description: `Run the commands in topological order`,
validator: isBoolean,
});

include = Option.String('--include', {
description: `List workspaces based on a glob pattern`,
validator: isString,
});

exclude = Option.String('--exclude', {
description: `Exclude workspaces based on a glob pattern`,
validator: isString,
});

noPrivate = Option.Boolean(`--no-private`, false, {
description: `Exclude private workspaces`,
validator: isBoolean,
});

/**
* Run the given command on the workspaces.
*
* @param workspaces - The workspaces to run the command on.
* @param commandName - The name of the command to run.
* @param args - The arguments to pass to the command.
* @return {Promise<void>}
*/
async run(workspaces, commandName, args) {
let extraArgs = [];
if (this.parallel) {
extraArgs.push('--parallel');
}

if (this.topological) {
extraArgs.push('--topological');
extraArgs.push('--topological-dev');
}

const includes = workspaces.map((workspace) => workspace.manifest.name)
.flatMap(({ scope, name }) => ['--include', `@${scope}/${name}`]);

await this.cli.run(['workspaces', 'foreach', '--verbose', ...includes, ...extraArgs, commandName, ...args], this.context);
}

async execute() {
// Note: We have to import `minimatch` here, because Yarn will always
// load the plugin, even if the command is not used, and `minimatch`
// may not be installed.
const { minimatch } = await import('minimatch');

const configuration = await Configuration.find(
this.context.cwd,
this.context.plugins,
);
const { project } = await Project.find(configuration, this.context.cwd);
const { workspaces } = project;

return report.exitCode();
if (!this.include && !this.exclude) {
throw new UsageError(
`This command requires at least one of --include or --exclude to be specified.`,
);
}

const filteredWorkspaces = workspaces.filter((workspace) => {
return (
(!this.include ||
minimatch(workspace.relativeCwd, this.include)) &&
(!this.exclude ||
!minimatch(workspace.relativeCwd, this.exclude))
);
}).filter((workspace) => {
return !this.noPrivate || !workspace.manifest.private;
});

return await this.run(filteredWorkspaces, this.commandName, this.args);
}
}

return {
commands: [FilterCommand],
commands: [FilterListCommand, FilterRunCommand],
};
},
};
Loading
Loading