├── .nvmrc ├── src ├── models │ ├── build.ts │ ├── merged-config.ts │ ├── pipeline.ts │ ├── README.md │ ├── abstract-step.ts │ ├── step.ts │ └── group-step.ts ├── index.ts ├── dynamodb.ts ├── buildkite │ ├── __mocks__ │ │ └── client.ts │ ├── client.ts │ └── config.ts ├── util │ ├── async.ts │ ├── got.ts │ ├── helper.ts │ ├── exec.ts │ ├── glob.ts │ └── tar.ts ├── branch-list.ts ├── commands │ ├── base-commit.ts │ ├── uninstall.ts │ ├── hash.ts │ ├── list.ts │ ├── pipeline.ts │ ├── deflate.ts │ ├── record-success.ts │ ├── download.ts │ ├── install.ts │ └── upload.ts ├── steps │ ├── nothing-to-do.ts │ ├── artifact-injection.ts │ └── record-success.ts ├── artifacts │ ├── compression │ │ ├── desync │ │ │ ├── config.ts │ │ │ └── seeds.ts │ │ ├── compressor.ts │ │ ├── tar.ts │ │ ├── gzip.ts │ │ ├── lz4.ts │ │ └── index.ts │ ├── api.ts │ └── model.ts ├── command.ts ├── git.ts ├── hash.ts ├── config-file.ts ├── annotate.ts ├── cache-metadata.ts ├── reason.ts ├── merge.ts └── manifest.ts ├── test ├── fixtures │ ├── baz │ ├── bar.tar.gz │ ├── foo.tar.lz4 │ ├── beep.catar.caibx │ ├── desync-store │ │ └── 61fe │ │ │ └── 61fe499ce7e969eeddc35c48901ac76265ce2929f8b8cccd9760ce8919245953.cacnk │ └── qux.tar ├── projects │ ├── pure │ │ ├── foo │ │ │ ├── README.md │ │ │ └── pipeline.yml │ │ └── baz │ │ │ ├── abc.ts │ │ │ └── pipeline.yml │ ├── kitchen-sink │ │ └── .buildkite │ │ │ ├── pipeline.malformed.yml │ │ │ ├── pipeline.match-all-env.yml │ │ │ ├── pipeline.unused.yml │ │ │ ├── pipeline.match-all.yml │ │ │ ├── pipeline.dependedon.yml │ │ │ ├── pipeline.unreferenced.yml │ │ │ ├── pipeline.match-all-true.yml │ │ │ ├── pipeline.match-all-false.yml │ │ │ ├── pipeline.some-long-name.yml │ │ │ ├── pipeline.match-all-mixed.yml │ │ │ ├── pipeline.changed.yml │ │ │ ├── pipeline.branch-excluded.yml │ │ │ ├── pipeline.excluded.yml │ │ │ ├── pipeline.included.yml │ │ │ ├── pipeline.qux.yml │ │ │ ├── pipeline.foo.yml │ │ │ ├── pipeline.baz.yml │ │ │ └── pipeline.bar.yml │ ├── flexible-structure │ │ ├── pipeline.yml │ │ ├── foo │ │ │ └── pipeline.foo2.yml │ │ └── pipelines │ │ │ └── can │ │ │ └── be │ │ │ └── anywhere │ │ │ └── pipeline.foo3.yml │ ├── invalid │ │ └── pipeline.invalid.yml │ ├── crossdeps │ │ └── .buildkite │ │ │ ├── pipeline.foo.yml │ │ │ └── pipeline.baz.yml │ ├── groups │ │ ├── pipeline.foo1.yml │ │ ├── pipeline.foo4.yml │ │ ├── pipeline.foo2.yml │ │ └── pipeline.foo3.yml │ ├── branch-exclusion │ │ └── .buildkite │ │ │ ├── pipeline.implicit-all.yml │ │ │ ├── pipeline.explicit-one.yml │ │ │ ├── pipeline.explicit-all.yml │ │ │ ├── pipeline.explicit-none.yml │ │ │ ├── pipeline.explicit-wildcards.yml │ │ │ ├── pipeline.implicit-rest.yml │ │ │ ├── pipeline.explicit-wildcard-end.yml │ │ │ ├── pipeline.explicit-include-exclude.yml │ │ │ ├── pipeline.explicit-include-exclude-wildcard.yml │ │ │ ├── pipeline.explicit-include-multiple.yml │ │ │ └── pipeline.explicit-exclude-multiple.yml │ ├── skipped │ │ └── .buildkite │ │ │ ├── pipeline.foo.yml │ │ │ └── pipeline.bar.yml │ └── bad-groups │ │ ├── pipeline.foo1.yml │ │ └── pipeline.foo2.yml ├── setup.ts ├── steps │ └── record-success.ts ├── models │ ├── step.test.ts │ └── group-step.test.ts ├── commands │ ├── list.test.ts │ ├── hash.test.ts │ ├── base-commit.test.ts │ ├── download.test.ts │ └── upload.test.ts ├── hash.test.ts ├── cache-metadata.test.ts ├── merge.test.ts ├── util │ └── helper.test.ts ├── buildkite │ └── client.test.ts ├── artifacts │ ├── model.test.ts │ └── compression.test.ts ├── config.test.ts ├── diff.test.ts ├── branch-list.test.ts └── manifest.test.ts ├── .dockerignore ├── .eslintignore ├── bin ├── run.cmd └── run ├── Brewfile ├── .prettierignore ├── jest-dynalite-config.js ├── tsconfig.eslint.json ├── .gitignore ├── .buildkite ├── monofo │ ├── pipeline.plugin-test.yml │ ├── pipeline.env.yml │ ├── pipeline.plugin-lint.yml │ ├── pipeline.typescript.yml │ ├── pipeline.node-modules.yml │ ├── pipeline.release.yml │ ├── pipeline.docker-node.yml │ └── pipeline.test.yml ├── plugin-lint └── buildkite │ └── pipeline.yml ├── .editorconfig ├── docs ├── commands │ ├── version.md │ ├── uninstall.md │ ├── pipeline.md │ ├── inflate.md │ ├── install.md │ ├── hash.md │ ├── autocomplete.md │ ├── list.md │ ├── base-commit.md │ ├── deflate.md │ ├── record-success.md │ ├── commands.md │ ├── upload.md │ └── download.md ├── plugin.md ├── diff.md ├── pure.md └── artifacts.md ├── .npmignore ├── hooks ├── lib │ ├── run.bash │ ├── download.bats │ ├── download.bash │ ├── generate.bats │ ├── upload.bats │ ├── generate.bash │ └── upload.bash ├── post-command ├── post-command.bats ├── pre-command └── pre-command.bats ├── docker-compose.local.yml ├── tsconfig.json ├── jest.config.js ├── .run ├── monofo deflate node-modules.tar node-modules.tar.lz4.run.xml └── monofo deflate node-modules.tar node-modules.caidx.run.xml ├── docker-compose.yml ├── plugin.yml ├── docker-compose.buildkite.yml ├── .eslintrc.js ├── Dockerfile └── .github └── renovate.json5 /.nvmrc: -------------------------------------------------------------------------------- 1 | lts/fermium 2 | -------------------------------------------------------------------------------- /src/models/build.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/baz: -------------------------------------------------------------------------------- 1 | qux 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /src/models/merged-config.ts: -------------------------------------------------------------------------------- 1 | // TODO 2 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | *.config.js 2 | .eslintrc.js 3 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { run } from '@oclif/core'; 2 | -------------------------------------------------------------------------------- /test/projects/pure/foo/README.md: -------------------------------------------------------------------------------- 1 | Example README 2 | -------------------------------------------------------------------------------- /bin/run.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | node "%~dp0\run" %* 4 | -------------------------------------------------------------------------------- /test/projects/pure/baz/abc.ts: -------------------------------------------------------------------------------- 1 | // Example Typescript file 2 | -------------------------------------------------------------------------------- /Brewfile: -------------------------------------------------------------------------------- 1 | tap "kaos/shell" 2 | brew "bats-support" 3 | brew "bats-assert" 4 | brew "bats-mock" 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # package.json is formatted by package managers, so we ignore it here 2 | package.json -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.malformed.yml: -------------------------------------------------------------------------------- 1 | steps: foo 2 | env: bar 3 | monorepo: baz 4 | -------------------------------------------------------------------------------- /test/fixtures/bar.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vital-software/monofo-buildkite-plugin/HEAD/test/fixtures/bar.tar.gz -------------------------------------------------------------------------------- /test/fixtures/foo.tar.lz4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vital-software/monofo-buildkite-plugin/HEAD/test/fixtures/foo.tar.lz4 -------------------------------------------------------------------------------- /jest-dynalite-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | tables: [require('./src/cache-metadata').CACHE_METADATA_TABLE_DEFINITION], 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/beep.catar.caibx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vital-software/monofo-buildkite-plugin/HEAD/test/fixtures/beep.catar.caibx -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.match-all-env.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: '**' 3 | 4 | env: 5 | MATCH_ALL_ENV: '1' 6 | -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.unused.yml: -------------------------------------------------------------------------------- 1 | env: 2 | NOPE: some-value 3 | 4 | steps: 5 | - command: echo "unused" 6 | -------------------------------------------------------------------------------- /src/models/pipeline.ts: -------------------------------------------------------------------------------- 1 | import { Step } from './step'; 2 | 3 | export interface Pipeline { 4 | steps: Step[]; 5 | env: Record; 6 | } 7 | -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.match-all.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: '**' 3 | 4 | steps: 5 | - command: echo "match-all" > match-all 6 | -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.dependedon.yml: -------------------------------------------------------------------------------- 1 | monorepo: {} 2 | 3 | steps: 4 | - command: 'echo "dependedon" > dependedon' 5 | key: dependedon 6 | -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.unreferenced.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: 3 | - "**" 4 | 5 | steps: 6 | - command: echo "unreferenced" > unref 7 | -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.match-all-true.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: true 3 | 4 | steps: 5 | - command: echo "match-all-true" > match-all-true 6 | -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.match-all-false.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: false 3 | 4 | steps: 5 | - command: echo "match-all-false" > match-all-false 6 | -------------------------------------------------------------------------------- /test/projects/flexible-structure/pipeline.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | name: foo1 3 | matches: "foo/**/README.md" 4 | 5 | steps: 6 | - command: echo "foo1" > foo1 7 | key: foo1Key 8 | -------------------------------------------------------------------------------- /test/projects/invalid/pipeline.invalid.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | produced: '<- wrong key' 3 | matched: '<- wrong key' 4 | depended_on: '<- wrong key' 5 | 6 | env: {} 7 | steps: [] 8 | -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.some-long-name.yml: -------------------------------------------------------------------------------- 1 | monorepo: {} 2 | 3 | steps: 4 | - command: 'echo "some-long-name" > some-long-name' 5 | key: some-long-name 6 | -------------------------------------------------------------------------------- /test/projects/flexible-structure/foo/pipeline.foo2.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | name: foo2 3 | matches: "foo/**/README.md" 4 | 5 | steps: 6 | - command: echo "foo2" > foo2 7 | key: foo2Key 8 | -------------------------------------------------------------------------------- /test/projects/crossdeps/.buildkite/pipeline.foo.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | produces: 3 | - .phony/foo 4 | matches: no-match 5 | 6 | steps: 7 | - command: echo "foo1" > foo1 8 | key: fooKey1 9 | -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.match-all-mixed.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: 3 | - "**/*" 4 | - "**" 5 | 6 | steps: 7 | - command: echo "match-all-mixed" > match-all-mixed 8 | -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.changed.yml: -------------------------------------------------------------------------------- 1 | # tests that changes to the pipeline itself are considered to match 2 | monorepo: {} 3 | 4 | steps: 5 | - command: echo "changed" > changed 6 | -------------------------------------------------------------------------------- /test/projects/pure/baz/pipeline.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | name: baz 3 | pure: true 4 | matches: baz/abc.ts 5 | produces: baz 6 | expects: foo 7 | 8 | steps: 9 | - command: echo "baz" > baz 10 | -------------------------------------------------------------------------------- /test/projects/flexible-structure/pipelines/can/be/anywhere/pipeline.foo3.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | name: foo3 3 | matches: "foo/**/README.md" 4 | 5 | steps: 6 | - command: echo "foo3" > foo3 7 | key: foo3Key 8 | -------------------------------------------------------------------------------- /test/setup.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path'; 2 | import { setup } from 'jest-dynalite'; 3 | import { fakeProcess } from './fixtures'; 4 | 5 | setup(resolve(__dirname, '../')); 6 | process.env = fakeProcess(process.env); 7 | -------------------------------------------------------------------------------- /tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": [ 4 | "src", 5 | "test", 6 | "test/**/*.json", 7 | "*.config.js", 8 | ".eslintrc.js", 9 | "*.json" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | *.log 4 | /.log* 5 | logs 6 | docker-compose.*override.yml 7 | .idea/ 8 | output/ 9 | oclif.manifest.json 10 | .combined-docs.md 11 | .eslintcache 12 | test/fixtures/desync-store/ 13 | -------------------------------------------------------------------------------- /test/projects/crossdeps/.buildkite/pipeline.baz.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | expects: 3 | - .phony/foo 4 | matches: 5 | - "baz/**/*.ts" # will match 6 | 7 | steps: 8 | - command: 'echo "baz1" | tee baz1' 9 | depends_on: fooKey1 10 | -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.branch-excluded.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: '**' 3 | 4 | # This excludes all branches explicitly because wildcard 5 | branches: '!*' 6 | 7 | steps: 8 | - command: echo "branch-excluded" > branch-excluded 9 | -------------------------------------------------------------------------------- /test/projects/groups/pipeline.foo1.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: "foo/**/README.md" 3 | produces: foo1 4 | 5 | steps: 6 | - group: "foo1 group" 7 | key: "foo1-group" 8 | steps: 9 | - command: echo "foo1" > foo1 10 | key: foo1 11 | -------------------------------------------------------------------------------- /test/projects/pure/foo/pipeline.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | name: foo 3 | pure: true 4 | matches: 5 | - foo/ # test matching dirs directly (they're not checksummed) 6 | - foo/README.md 7 | produces: foo 8 | 9 | steps: 10 | - command: echo "foo" > foo 11 | -------------------------------------------------------------------------------- /test/fixtures/desync-store/61fe/61fe499ce7e969eeddc35c48901ac76265ce2929f8b8cccd9760ce8919245953.cacnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vital-software/monofo-buildkite-plugin/HEAD/test/fixtures/desync-store/61fe/61fe499ce7e969eeddc35c48901ac76265ce2929f8b8cccd9760ce8919245953.cacnk -------------------------------------------------------------------------------- /test/projects/branch-exclusion/.buildkite/pipeline.implicit-all.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: '**' 3 | 4 | # This includes all branches implicitly because branches not defined 5 | 6 | steps: 7 | - command: echo "implicit-all" > implicit-all 8 | key: implicit-all 9 | -------------------------------------------------------------------------------- /src/models/README.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | - Move Steps from types to here, in particular GroupStep which has a number of supporting functions 4 | - Create a MergedConfig model, holding the Config[] collection, can act on the aggregate, start to form the basis of access in decisions 5 | -------------------------------------------------------------------------------- /test/projects/branch-exclusion/.buildkite/pipeline.explicit-one.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: '**' 3 | 4 | # This includes one branch (only) explicitly 5 | branches: 'one' 6 | 7 | steps: 8 | - command: echo "explicit-one" > explicit-one 9 | key: explicit-one 10 | -------------------------------------------------------------------------------- /test/projects/skipped/.buildkite/pipeline.foo.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | produces: 3 | - foo1 4 | matches: "no-match" 5 | 6 | steps: 7 | - command: echo "foo1" > foo1 8 | key: fooKey1 9 | plugins: 10 | - artifacts#v1.3.0: 11 | upload: foo1 12 | -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.excluded.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | # This does match, but this pipeline is excluded with PIPELINE_NO_RUN_EXCLUDED=1 3 | matches: 4 | - "foo/**/README.md" 5 | 6 | steps: 7 | - command: echo "excluded" > excluded 8 | key: excluded 9 | -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.included.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | # This does NOT match, but this pipeline is included with PIPELINE_RUN_INCLUDED=1 3 | matches: 4 | - "included/no-match" 5 | 6 | steps: 7 | - command: echo "included" > included 8 | key: included 9 | -------------------------------------------------------------------------------- /test/projects/branch-exclusion/.buildkite/pipeline.explicit-all.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: '**' 3 | 4 | # This includes all branches explicitly because wildcard 5 | branches: '*' 6 | 7 | steps: 8 | - command: echo "explicit-all" > explicit-all 9 | key: explicit-all 10 | -------------------------------------------------------------------------------- /test/projects/branch-exclusion/.buildkite/pipeline.explicit-none.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: '**' 3 | 4 | # This excludes all branches explicitly because wildcard 5 | branches: '!*' 6 | 7 | steps: 8 | - command: echo "explicit-none" > explicit-none 9 | key: explicit-none 10 | -------------------------------------------------------------------------------- /test/projects/groups/pipeline.foo4.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: "foo/**/README.md" 3 | expects: foo1 4 | 5 | steps: 6 | - group: "foo4 group" 7 | key: "foo4-group" 8 | depends_on: foo1-group 9 | steps: 10 | - command: echo "foo4" > foo4 11 | key: foo4 12 | -------------------------------------------------------------------------------- /test/projects/bad-groups/pipeline.foo1.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: "foo/**/README.md" 3 | produces: foo1 4 | 5 | steps: 6 | - group: "foo1 group" 7 | key: "foo1-group" 8 | allow_dependency_failure: false 9 | steps: 10 | - command: echo "foo1" > foo1 11 | key: foo1 12 | -------------------------------------------------------------------------------- /test/projects/branch-exclusion/.buildkite/pipeline.explicit-wildcards.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: '**' 3 | 4 | # This includes some branches by wildcards 5 | branches: 'feature/*' 6 | 7 | steps: 8 | - command: echo "explicit-wildcards" > explicit-wildcards 9 | key: explicit-wildcards 10 | -------------------------------------------------------------------------------- /test/projects/branch-exclusion/.buildkite/pipeline.implicit-rest.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: '**' 3 | 4 | # This excludes one branch explicitly, and includes the rest implicitly 5 | branches: '!one' 6 | 7 | steps: 8 | - command: echo "implicit-rest" > implicit-rest 9 | key: implicit-rest 10 | -------------------------------------------------------------------------------- /.buildkite/monofo/pipeline.plugin-test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | monorepo: 4 | pure: true 5 | matches: 6 | - hooks/** 7 | 8 | steps: 9 | - name: ":bash: Bash Tests" 10 | key: plugin-test 11 | timeout_in_minutes: 20 12 | plugins: 13 | - docker-compose#v3.9.0: 14 | run: plugin-test 15 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /docs/commands/version.md: -------------------------------------------------------------------------------- 1 | `monofo version` 2 | ================ 3 | 4 | 5 | 6 | * [`monofo version`](#monofo-version) 7 | 8 | ## `monofo version` 9 | 10 | ``` 11 | USAGE 12 | $ monofo version 13 | ``` 14 | 15 | _See code: [@oclif/plugin-version](https://github.com/oclif/plugin-version/blob/v1.0.4/src/commands/version.ts)_ 16 | -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.qux.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | expects: 3 | - foo1 4 | produces: 5 | - qux1 6 | matches: qux/no-match 7 | 8 | steps: 9 | - command: echo "qux1" 10 | plugins: 11 | - artifacts#v1.3.0: 12 | download: foo1 13 | upload: 14 | - from: qux/qux1 15 | to: qux1 16 | -------------------------------------------------------------------------------- /test/projects/branch-exclusion/.buildkite/pipeline.explicit-wildcard-end.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: '**' 3 | 4 | # This includes some branches by wildcards, if not excluded by other wildcards 5 | branches: 'feature/*-included !feature/*-excluded' 6 | 7 | steps: 8 | - command: echo "explicit-wildcard-end" > explicit-wildcard-end 9 | key: explicit-wildcard-end 10 | -------------------------------------------------------------------------------- /test/projects/groups/pipeline.foo2.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: "foo/**/README.md" 3 | 4 | # This tests our ability to stitch together groups, because otherwise Buildkite only supports appending to groups from later uploads 5 | 6 | steps: 7 | - group: "foo1 group" 8 | key: "foo1-group" 9 | steps: 10 | - command: echo "foo2" > foo2 11 | key: foo2 12 | -------------------------------------------------------------------------------- /test/projects/groups/pipeline.foo3.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: "foo/**/README.md" 3 | expects: foo1 4 | 5 | # This tests the group step depends_on property 6 | 7 | steps: 8 | - group: "foo3 group" 9 | key: "foo3-group" 10 | depends_on: 11 | - foo1-group 12 | - foo1 13 | steps: 14 | - command: echo "foo3" > foo3 15 | key: foo3 16 | -------------------------------------------------------------------------------- /test/projects/branch-exclusion/.buildkite/pipeline.explicit-include-exclude.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: '**' 3 | 4 | # This includes some branches by wildcards, if not excluded by other wildcards 5 | branches: 'feature/* !feature/excluded' 6 | 7 | steps: 8 | - command: echo "explicit-include-exclude" > explicit-include-exclude 9 | key: explicit-include-exclude 10 | -------------------------------------------------------------------------------- /test/steps/record-success.ts: -------------------------------------------------------------------------------- 1 | import { recordSuccessSteps } from '../../src/steps/record-success'; 2 | import { selectScenario } from '../fixtures'; 3 | 4 | describe('recordSuccessSteps', () => { 5 | it('returns steps when given relevant configs', async () => { 6 | selectScenario('pure'); 7 | await expect(recordSuccessSteps([])).resolves.toHaveLength(0); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/projects/bad-groups/pipeline.foo2.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: "foo/**/README.md" 3 | 4 | steps: 5 | - group: "foo1 group" 6 | key: "foo1-group" 7 | 8 | # We'd normally be able to merge these definitions, but this being different means we can't, so we should error 9 | allow_dependency_failure: true 10 | 11 | steps: 12 | - command: echo "foo2" > foo2 13 | key: foo2 14 | -------------------------------------------------------------------------------- /test/projects/branch-exclusion/.buildkite/pipeline.explicit-include-exclude-wildcard.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: '**' 3 | 4 | # This includes some branches by wildcards, if not excluded by other wildcards 5 | branches: 'feature/* !feature/exclude*' 6 | 7 | steps: 8 | - command: echo "explicit-include-exclude-wildcard" > explicit-include-exclude-wildcard 9 | key: explicit-include-exclude-wildcard 10 | -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.foo.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | produces: 3 | - foo1 4 | matches: 5 | - "foo/**/*.ts" 6 | - "foo/**/README.md" 7 | depends_on: dependedon 8 | 9 | env: 10 | FOO: some-value 11 | FOO2: another-value 12 | 13 | steps: 14 | - command: echo "foo1" > foo1 15 | key: fooKey1 16 | plugins: 17 | - artifacts#v1.3.0: 18 | upload: foo1 19 | -------------------------------------------------------------------------------- /src/models/abstract-step.ts: -------------------------------------------------------------------------------- 1 | export interface ArtifactPluginConfig { 2 | 'artifacts#v1.3.0': { 3 | build: string; 4 | upload: string[]; 5 | download: string[]; 6 | }; 7 | } 8 | 9 | export interface AbstractStep { 10 | depends_on?: string | string[]; 11 | key?: string; 12 | label?: string; 13 | plugins?: (Record | ArtifactPluginConfig)[]; 14 | [others: string]: unknown; 15 | } 16 | -------------------------------------------------------------------------------- /test/projects/branch-exclusion/.buildkite/pipeline.explicit-include-multiple.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: '**' 3 | 4 | # This includes some branches by wildcards, if not excluded by other wildcards 5 | branches: 'feature/include-one feature/include-two feature/include-three' 6 | 7 | steps: 8 | - command: echo "explicit-include-exclude-wildcard" > explicit-include-exclude-wildcard 9 | key: explicit-include-exclude-wildcard 10 | -------------------------------------------------------------------------------- /.buildkite/plugin-lint: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # Combines the documentation in the README file ahead of plugin lint 3 | # 4 | # This is because the plugin lint container can only examine a single Markdown 5 | # file to find code examples, but we want it to check all our documentation 6 | set -eu 7 | 8 | cat /plugin/README.md /plugin/docs/*.md > /plugin/.combined-docs.md 9 | exec lint --id vital-software/monofo --readme .combined-docs.md "${@}" 10 | -------------------------------------------------------------------------------- /test/projects/branch-exclusion/.buildkite/pipeline.explicit-exclude-multiple.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | matches: '**' 3 | 4 | # This includes some branches by wildcards, if not excluded by other wildcards 5 | branches: 'feature/* !feature/exclude-one !feature/exclude-two !feature/exclude-three' 6 | 7 | steps: 8 | - command: echo "explicit-include-exclude-wildcard" > explicit-include-exclude-wildcard 9 | key: explicit-include-exclude-wildcard 10 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | tsconfig.json 3 | .eslintrc.js 4 | .circleci 5 | .idea/ 6 | *.config.js 7 | .github 8 | .prettierignore 9 | .vscode 10 | dist/docs 11 | dist/test 12 | __mocks__ 13 | **/*.spec.* 14 | **/*.test.* 15 | test/ 16 | .buildkite/ 17 | coverage 18 | *.log 19 | .editorconfig 20 | *.tgz 21 | *.tar.lz4 22 | .dockerignore 23 | scripts 24 | Dockerfile 25 | docker-compose.*.yml 26 | docker-compose.yml 27 | .log* 28 | .eslintignore 29 | dist/test/* 30 | yarn.lock 31 | -------------------------------------------------------------------------------- /src/dynamodb.ts: -------------------------------------------------------------------------------- 1 | import { DynamoDB } from '@aws-sdk/client-dynamodb'; 2 | import { DynamoDBDocument } from '@aws-sdk/lib-dynamodb'; 3 | 4 | export const service: DynamoDB = new DynamoDB({ 5 | ...(process.env.MOCK_DYNAMODB_ENDPOINT 6 | ? { 7 | endpoint: process.env.MOCK_DYNAMODB_ENDPOINT, 8 | sslEnabled: false, 9 | region: 'local', 10 | } 11 | : {}), 12 | }); 13 | 14 | export const client: DynamoDBDocument = DynamoDBDocument.from(service); 15 | -------------------------------------------------------------------------------- /hooks/lib/run.bash: -------------------------------------------------------------------------------- 1 | [[ "${BASH_SOURCE[0]}" == "${0}" ]] && echo "Not for direct execution" && exit 2 || true 2 | set -euo pipefail 3 | 4 | # This version marker is automatically updated to match the published release 5 | export MONOFO_VERSION=${MONOFO_VERSION:-5.0.12} 6 | 7 | # This turns on debugging for monofo, which is important to see what's going on 8 | export DEBUG="monofo:*" 9 | 10 | function monofo() { 11 | echo "npx --quiet --shell sh monofo@$MONOFO_VERSION ${*}" 12 | } 13 | -------------------------------------------------------------------------------- /src/buildkite/__mocks__/client.ts: -------------------------------------------------------------------------------- 1 | // @todo This unfortunately can't live in test/buildkite/__mocks__, see https://github.com/facebook/jest/issues/2726 2 | 3 | import { fakeBuildkiteBuildsListing } from '../../../test/fixtures'; 4 | 5 | export const mockGetBuilds = jest.fn().mockImplementation(() => Promise.resolve(fakeBuildkiteBuildsListing())); 6 | 7 | const mock = jest.fn().mockImplementation(() => { 8 | return { getBuilds: mockGetBuilds }; 9 | }); 10 | 11 | export default mock; 12 | -------------------------------------------------------------------------------- /docker-compose.local.yml: -------------------------------------------------------------------------------- 1 | version: "2.3" 2 | 3 | # How to override the configuration when doing development, so that yarn 4 | # packages from the local system are used. 5 | services: 6 | node: {} 7 | # volumes: 8 | # # MacOS 9 | # - source: ~/Library/Caches/Yarn/v6 10 | # target: /usr/local/share/.cache/yarn/v6 11 | # type: bind 12 | # # Linux: 13 | # - source: ~/.cache/yarn/v6 14 | # target: /usr/local/share/.cache/yarn/v6 15 | # type: bind 16 | -------------------------------------------------------------------------------- /src/util/async.ts: -------------------------------------------------------------------------------- 1 | export function mapAsync( 2 | array: I[], 3 | callback: (value: I, index: number, array: I[]) => Promise 4 | ): Promise { 5 | return Promise.all(array.map(callback)); 6 | } 7 | 8 | export async function filterAsync( 9 | array: T[], 10 | callback: (value: T, index: number, array: T[]) => Promise 11 | ): Promise { 12 | const filterMap = await mapAsync(array, callback); 13 | return array.filter((_, index) => filterMap[index]); 14 | } 15 | -------------------------------------------------------------------------------- /.buildkite/monofo/pipeline.env.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | env: 4 | BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG_0: "docker-compose.yml" 5 | BUILDKITE_PLUGIN_DOCKER_COMPOSE_CONFIG_1: "docker-compose.buildkite.yml" 6 | MONOFO_DESYNC_STORE: "s3+https://s3-us-west-2.amazonaws.com/vital-buildkite-cache-us-west-2/desync/store" 7 | MONOFO_DESYNC_CACHE: "/tmp/monofo/desync-store" 8 | MONOFO_DESYNC_SEED_DIR: "/tmp/monofo/desync-seeds" 9 | NODE_ENV: development 10 | 11 | monorepo: 12 | matches: true 13 | 14 | steps: [] 15 | -------------------------------------------------------------------------------- /.buildkite/monofo/pipeline.plugin-lint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | monorepo: 4 | pure: true 5 | matches: 6 | - plugin.yml 7 | - "**/*.md" 8 | - .buildkite/plugin-lint 9 | 10 | steps: 11 | - name: ":buildkite: Plugin Lint" 12 | key: plugin-lint 13 | timeout_in_minutes: 20 14 | plugins: 15 | - docker-compose#v3.9.0: 16 | run: plugin-lint 17 | soft_fail: # until we can fix https://github.com/buildkite-plugins/buildkite-plugin-linter/issues/409 18 | - exit_status: 1 19 | -------------------------------------------------------------------------------- /src/branch-list.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | 3 | export interface ParsedBranchList { 4 | allowed: string[]; 5 | blocked: string[]; 6 | } 7 | 8 | export function parseBranchList(branchList?: string): ParsedBranchList { 9 | if (!branchList) { 10 | return { 11 | allowed: [], 12 | blocked: [], 13 | }; 14 | } 15 | 16 | const [allowed, blocked] = _.partition(branchList.split(' '), (item) => item.indexOf('!')); 17 | 18 | return { 19 | allowed, 20 | blocked, 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.baz.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | expects: 3 | - foo1 4 | - bar2 5 | - qux1 6 | produces: 7 | - baz1 8 | matches: baz/** 9 | 10 | env: 11 | BAZ: some-value 12 | 13 | steps: 14 | - command: echo "baz1" 15 | key: baz1 16 | depends_on: 17 | - fooKey1 18 | - barKey1 19 | - barKey2 20 | plugins: 21 | - artifacts#v1.3.0: 22 | download: [foo1, bar2] 23 | upload: 24 | - from: baz/baz1 25 | to: baz1 26 | -------------------------------------------------------------------------------- /bin/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // @see https://github.com/oclif/hello-world/blob/b9a3dbccf2a3ebfdadbe4bf0767ecfa2eda9b4e1/bin/run 3 | 4 | const fs = require('fs') 5 | const path = require('path') 6 | 7 | if (!fs.existsSync(path.join(__dirname, '../dist'))) { 8 | throw new Error("Monofo expects to run with Typescript compiled; try running yarn build") 9 | } 10 | 11 | const oclif = require('@oclif/core') 12 | oclif.settings.tsnodeEnabled = false 13 | oclif.run().then(require('@oclif/core/flush')).catch(require('@oclif/core/handle')) 14 | -------------------------------------------------------------------------------- /test/models/step.test.ts: -------------------------------------------------------------------------------- 1 | import Config from '../../src/models/config'; 2 | import { keysInSteps } from '../../src/models/step'; 3 | import { getProjectFixturePath } from '../fixtures'; 4 | 5 | describe('keysInSteps', () => { 6 | it('gets recursive keys', async () => { 7 | const configs = await Config.getAll(getProjectFixturePath('groups')); 8 | const keys = configs.map((config) => keysInSteps(config.steps)); 9 | 10 | expect(keys).toStrictEqual([ 11 | ['foo1-group', 'foo1'], 12 | ['foo1-group', 'foo2'], 13 | ['foo3-group', 'foo3'], 14 | ['foo4-group', 'foo4'], 15 | ]); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /test/projects/skipped/.buildkite/pipeline.bar.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | expects: 3 | - foo1 4 | produces: 5 | - bar1 6 | - bar2 7 | matches: no-match 8 | excluded_steps: 9 | - label: "Some other step" 10 | command: "echo 'bar was replaced'" 11 | 12 | steps: 13 | - command: 'echo "bar1" | tee bar1' 14 | key: barKey1 15 | depends_on: fooKey1 16 | plugins: 17 | - artifacts#v1.3.0: 18 | download: foo1 19 | upload: bar1 20 | 21 | - command: 'echo "bar2" | tee bar2' 22 | key: barKey2 23 | plugins: 24 | - artifacts#v1.3.0: 25 | download: foo1 26 | upload: bar2 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "rootDir": ".", 5 | "moduleResolution": "node", 6 | 7 | "declaration": true, 8 | "declarationMap": true, 9 | "emitDecoratorMetadata": true, 10 | "esModuleInterop": true, 11 | "experimentalDecorators": true, 12 | "inlineSourceMap": true, 13 | "noFallthroughCasesInSwitch": true, 14 | "noImplicitOverride": true, 15 | "noImplicitReturns": true, 16 | "noUnusedParameters": true, 17 | "resolveJsonModule": true, 18 | "sourceRoot": "", 19 | }, 20 | "include": ["src", "test", "bin/*.js"], 21 | "extends": "@tsconfig/node14/tsconfig.json" 22 | } 23 | -------------------------------------------------------------------------------- /test/commands/list.test.ts: -------------------------------------------------------------------------------- 1 | import List from '../../src/commands/list'; 2 | import { fakeProcess, selectScenario, testRun } from '../fixtures'; 3 | 4 | jest.mock('../../src/git'); 5 | jest.mock('../../src/buildkite/client'); 6 | 7 | describe('monofo list', () => { 8 | it('returns help output', async () => { 9 | return expect(testRun(List, ['--help'])).rejects.toThrowError('EEXIT: 0'); 10 | }); 11 | 12 | it('returns matching files for the pure scenario', async () => { 13 | process.env = fakeProcess(); 14 | selectScenario('pure'); 15 | 16 | const { stdout } = await testRun(List, ['foo']); 17 | expect(stdout).toContain('foo/README.md'); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /src/commands/base-commit.ts: -------------------------------------------------------------------------------- 1 | import { getBuildkiteInfo } from '../buildkite/config'; 2 | import { BaseCommand } from '../command'; 3 | import { getBaseBuild } from '../diff'; 4 | 5 | export default class BaseCommit extends BaseCommand { 6 | static override description = 'output a base commit hash, against which the current build would be compared'; 7 | 8 | static override examples = [ 9 | `$ monofo base-commit 10 | 6c4fe0eda8b93de6764c3f99758505f0e4370103 11 | `, 12 | ]; 13 | 14 | static override flags = { ...BaseCommand.flags }; 15 | 16 | async run() { 17 | const base = await getBaseBuild(getBuildkiteInfo(process.env)); 18 | process.stdout.write(`${base.commit}\n`); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/steps/nothing-to-do.ts: -------------------------------------------------------------------------------- 1 | import Config from '../models/config'; 2 | import { CommandStep, Step } from '../models/step'; 3 | 4 | const NOTHING_TO_DO_STEP_LABEL = `:white_check_mark: :shrug: Nothing to do`; 5 | 6 | /** 7 | * When no subcomponents match, pop a message onto the build 8 | * 9 | * @todo add a block step, ask the user if they want to do a full build? 10 | */ 11 | export function nothingToDoSteps(configs: Config[]): Step[] { 12 | if (configs.find((v) => v.included)) { 13 | return []; 14 | } 15 | 16 | return [ 17 | { 18 | label: NOTHING_TO_DO_STEP_LABEL, 19 | key: 'nothing-to-do', 20 | command: `echo 'All build parts were skipped'`, 21 | } as CommandStep, 22 | ]; 23 | } 24 | -------------------------------------------------------------------------------- /test/commands/hash.test.ts: -------------------------------------------------------------------------------- 1 | import Hash from '../../src/commands/hash'; 2 | import { fakeProcess, selectScenario, testRun } from '../fixtures'; 3 | 4 | jest.mock('../../src/git'); 5 | jest.mock('../../src/buildkite/client'); 6 | 7 | describe('monofo hash', () => { 8 | it('returns help output', async () => { 9 | return expect(testRun(Hash, ['--help'])).rejects.toThrowError('EEXIT: 0'); 10 | }); 11 | 12 | it('returns the content hash for the pure scenario', async () => { 13 | process.env = fakeProcess(); 14 | selectScenario('pure'); 15 | 16 | const { stdout } = await testRun(Hash, ['foo']); 17 | expect(stdout).toContain('0ffe034c45380e93a2f65d67d8c286a237b00285233c91b778ba70f860c7b54a'); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | /** @typedef {import('ts-jest')} */ 2 | /** @type {import('@jest/types').Config.InitialOptions} */ 3 | const config = { 4 | transform: { 5 | '^.+\\.tsx?$': require.resolve('ts-jest') 6 | }, 7 | testEnvironment: 'node', 8 | verbose: true, 9 | collectCoverageFrom: ['src/**/*.ts', '!**/node_modules/**', '!**/test/**'], 10 | coverageReporters: ['lcov', 'text'], 11 | coverageDirectory: '/output/coverage/', 12 | moduleFileExtensions: ['ts', 'js'], 13 | modulePaths: ['/src/', '/test/', '/node_modules/'], 14 | testRegex: '.*\\.test.ts$', 15 | roots: ["/src", "/test"], 16 | setupFiles: ["/test/setup.ts"], 17 | }; 18 | 19 | module.exports = config; 20 | -------------------------------------------------------------------------------- /test/projects/kitchen-sink/.buildkite/pipeline.bar.yml: -------------------------------------------------------------------------------- 1 | monorepo: 2 | expects: 3 | - foo1 4 | produces: 5 | - bar1 6 | - bar2 7 | matches: bar/no-match 8 | excluded_steps: 9 | - label: "Some other step" 10 | command: "echo 'bar was replaced'" 11 | excluded_env: 12 | BAR_WAS_EXCLUDED: "true" 13 | 14 | env: 15 | BAR: some-value 16 | 17 | steps: 18 | - command: 'echo "bar1" | tee bar1' 19 | key: barKey1 20 | depends_on: fooKey1 21 | plugins: 22 | - artifacts#v1.3.0: 23 | download: foo1 24 | upload: bar1 25 | 26 | - command: 'echo "bar2" | tee bar2' 27 | key: barKey2 28 | plugins: 29 | - artifacts#v1.3.0: 30 | download: foo1 31 | upload: bar2 32 | -------------------------------------------------------------------------------- /.buildkite/monofo/pipeline.typescript.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | monorepo: 4 | pure: true 5 | expects: node-modules.catar.caibx 6 | matches: 7 | - "**/*.ts" 8 | - tsconfig.json 9 | - package.json 10 | - yarn.lock 11 | produces: typescript.catar.caibx 12 | 13 | steps: 14 | - name: ":typescript: Build" 15 | key: typescript 16 | depends_on: 17 | - node-image 18 | - node-modules 19 | commands: 20 | - yarn build 21 | timeout_in_minutes: 20 22 | plugins: 23 | - docker-compose#v3.9.0: 24 | run: node 25 | - vital-software/monofo#v5.0.11: 26 | download: 27 | - node-modules.catar.caibx 28 | upload: 29 | typescript.catar.caibx: 30 | - ./dist/ 31 | -------------------------------------------------------------------------------- /test/hash.test.ts: -------------------------------------------------------------------------------- 1 | import { FileHasher } from '../src/hash'; 2 | import { selectScenario } from './fixtures'; 3 | 4 | describe('class FileHasher', () => { 5 | describe('hashOne()', () => { 6 | it('receives changes and hashes file contents', async () => { 7 | selectScenario('pure'); 8 | 9 | const hasher = new FileHasher(); 10 | 11 | // Hashes are consistent 12 | expect(await hasher.hashMany(['foo/README.md', 'baz/abc.ts'])).toBe( 13 | await hasher.hashMany(['foo/README.md', 'baz/abc.ts']) 14 | ); 15 | 16 | // And order independent 17 | expect(await hasher.hashMany(['foo/README.md', 'baz/abc.ts'])).toBe( 18 | await hasher.hashMany(['baz/abc.ts', 'foo/README.md']) 19 | ); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /docs/commands/uninstall.md: -------------------------------------------------------------------------------- 1 | `monofo uninstall` 2 | ================== 3 | 4 | Uninstalls the Monofo DynamoDB tables 5 | 6 | * [`monofo uninstall`](#monofo-uninstall) 7 | 8 | ## `monofo uninstall` 9 | 10 | Uninstalls the Monofo DynamoDB tables 11 | 12 | ``` 13 | USAGE 14 | $ monofo uninstall [-C ] [-v] [-V] [-h] 15 | 16 | FLAGS 17 | -C, --chdir= Directory to change to before executing command 18 | -V, --version Show CLI version. 19 | -h, --help Show this help message 20 | -v, --verbose Run with verbose logging 21 | 22 | DESCRIPTION 23 | Uninstalls the Monofo DynamoDB tables 24 | ``` 25 | 26 | _See code: [dist/src/commands/uninstall.ts](https://github.com/vital-software/monofo/blob/v5.0.1/dist/src/commands/uninstall.ts)_ 27 | -------------------------------------------------------------------------------- /hooks/post-command: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Post-command hook 3 | # 4 | # This script just interprets a couple of key settings, and then calls into the 5 | # relevant sub-script in lib/ 6 | 7 | set -euo pipefail 8 | 9 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 10 | 11 | if [[ "${MONOFO_HOOK_DEBUG:-0}" -eq 1 ]]; then 12 | set -x 13 | export DEBUG="*" 14 | fi 15 | 16 | if [[ -z "${BUILDKITE_PLUGIN_CONFIGURATION:-}" ]]; then 17 | echo "Expected BUILDKITE_PLUGIN_CONFIGURATION to be set" >&2 18 | exit 1 19 | fi 20 | 21 | upload=$(jq -cr 'has("upload")' <<< "$BUILDKITE_PLUGIN_CONFIGURATION") 22 | 23 | if [[ "$upload" == "true" ]]; then 24 | # shellcheck source=./lib/upload.bash 25 | source "${SCRIPT_DIR}/lib/upload.bash" 26 | fi 27 | -------------------------------------------------------------------------------- /.run/monofo deflate node-modules.tar node-modules.tar.lz4.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |