Git Product home page Git Product logo

lage's Introduction

lage

Documentation is here: https://microsoft.github.io/lage/

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

lage's People

Contributors

adityag221 avatar adjective-object avatar akimalunar avatar altinokdarici avatar benkroeger avatar bilgedenizkocakk avatar brandonthomas avatar brunords avatar bryan-cee avatar christiango avatar dannyvv avatar dependabot[bot] avatar ecraig12345 avatar kenotron avatar microsoft-github-operations[bot] avatar microsoftopensource avatar oliwheeler avatar philip-scott avatar phillipb avatar pushkargupta9807 avatar renovate[bot] avatar ronaldndirangu avatar sasandhu avatar sstchur avatar sverrejoh avatar tido64 avatar viditganpi avatar vkrol avatar woovik avatar zoidyzoidzoid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lage's Issues

lage should fail on invalid commands, args and arg values

We had a recent ADO Tools failure that was passing garbage args to lage like:

lage info build ut --since refs/remotes/origin/master##vso[task.debug]Exit code 0 received from tool '/bin/bash' --production --verbose --grouped

However, lage seems to be too lenient with garbage / invalid, resulting in "false positives":

info Lage task runner - let's make it
verb filterPackages changed: 
verb filterPackages running with dependents
info 🏗 Summary
info 
info Nothing has been run.
info ----------------------------------------------
info Took a total of 0.14s to complete
Done in 0.79s.

This allows PRs that didn't build or run tests to appear to be "passing" but then broke master after merge.

I think lage should fail harder on invalid commands and args to both prevent CI from generating "false positives" and also more clearly highlight issues with tools, like this ADO tool issue.

--since flag does not behave well for changes in global files

Scenario 1:

  • I have a change to an RFC file
  • expected behavior: Lage builds nothing
  • current behavior: Lage builds everything

Scenario 2:

  • I have a change to a global config file and a file in the package foo
  • expected behavior: Lage builds everything
  • current behavior: Lage builds is scoped to foo

Allow extra logger configurations

By providing additional logger options, we should be able to better customize Lage's output. By using NPMLogger this customization is already possible, Lage should provide a parameter that accepts changes to NPMLogger disp, styles, levels.

Additionally, it would be helpful to be able to specify the log level to be used.

Allow package-local cache configuration

Lage determines non-default backfill cache options from the root-level lage config or environment variables (see https://github.com/microsoft/lage/blob/ddfb24e8d7f57359a57473f0e9205c0f5ccbf94a/src/cache/cacheConfig.ts). This means that package-relative output globs must be specified globally.

Not all packages are able to share the same output structure. In react-native-windows, some packages have build outputs that should not be generalized. Allowing pacakge-local backfill configuration would allow scoping the determination of build outputs to individual packages.

Make a lage info command that spits out the graph

sample lage info output

[
    {
        "id": "bar##build",
        "package": "bar",
        "task": "build",
        "command": "npm run build --blah",
        "workingDirectory": "packages/bar",
        "dependencies": []
    },
    {
        "id": "foo##build",
        "package": "foo",
        "task": "build",
        "command": "npm run build --blah",
        "workingDirectory": "packages/foo",
        "dependencies": [
            "bar##build"
        ]
    },
    {
        "id": "foo##test",
        "package": "foo",
        "task": "test",
        "command": "npm run test --blah",
        "workingDirectory": "packages/foo",
        "dependencies": [
            "foo##build"
        ]
    },
    ...
]

Invert --no-deps flag to be default on scoped execution

According to the docs, the task will run on the dependants of the scoped packages unless the --no-deps flag is passed.

It would be nicer if this was inverted so that the default case was to run the tasks excluding dependants and have a flag, say --include-dependants to run the task for dependants.

This would save typing for developers when running tasks in their local dev loop.
The --include-dependants flag can be used in CI scripts.

Package level lage.config.js

Does lage support package level lage.config.js? Currently, we have a huge repo with multiple packages in it. At the root of the repo we have a lage.config.js that has pipeline definitions for all the packages in the repo. However, there are some packages that have pipeline demands different from those defined in the root lage.config.js. We want to override the root lage.config.js for these packages.
Now, we know that lage supports package level configs via specific-package-tasks. However, since our repo is huge and this list of packages can get really long, this approach can quickly become impractical. Hence, we are looking if there's a way to define a lage.config.js in each such package that overrides the root lage.config.js. For example we can have a task:[] in the root lage.config and each of these special packages can have a lage.config with task:[task1]. If lage doesn't plan to implement this or doesn't has this already, could someone please explain the cons of the above approach from lage's perspective?

This is just what we had in mind and we are very eager to know any other similar workarounds as well.

Lage returns exit code 0 on failure in workspace-tools

When using lage without a master branch, it will fail, because workspace-tools can't find the hard coded master branch...
I have a fix for that, but this issue tracks the fact that lage exist with exit code 0 instead of a non-zero one causing validation pipelines to succeed in this step.
Hopefully failing later and not continuing thinking all is good :)

yarn run v1.22.10
$ lage build
info Lage task runner - let's make it
(node:24264) UnhandledPromiseRejectionWarning: Error: fatal: ambiguous argument 'origin/master...': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
    at Object.getBranchChanges (D:\src\azure-devops-symbols\node_modules\workspace-tools\lib\git.js:126:15)
    at Object.getChangedPackages (D:\src\azure-devops-symbols\node_modules\workspace-tools\lib\workspaces\getChangedPackages.js:33:23)
    at Object.getWorkspace (D:\src\azure-devops-symbols\node_modules\lage\lib\workspace\getWorkspace.js:16:44)
    at Object.run (D:\src\azure-devops-symbols\node_modules\lage\lib\command\run.js:14:38)
    at Object.<anonymous> (D:\src\azure-devops-symbols\node_modules\lage\lib\index.js:28:19)
    at Module._compile (internal/modules/cjs/loader.js:1015:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1035:10)
    at Module.load (internal/modules/cjs/loader.js:879:32)
    at Function.Module._load (internal/modules/cjs/loader.js:724:14)
    at Module.require (internal/modules/cjs/loader.js:903:19)
(node:24264) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:24264) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Done in 0.96s.

--grouped truncates long build output

With the --grouped option and a task with very long output, some of the output is getting truncated (at least on errors). This is a problem because it can make determining the source of an error impossible--2 examples in this build. I've disabled grouped builds in Fluent UI for now (microsoft/fluentui#16019) so that we can actually debug these issues, but I'd like to re-enable the option since it's a better experience in general.

feature request: bypass the cache for only one script name

the --no-cache cli option allows Lage to not use the cache, but this apply to all the tasks it runs.
We need to way to specify in the config file that a given script will always bypass the cache (because it produces some side effects which are not cacheable).

Error on invalid / undefined commands

I've noticed sometimes when I typo lage doesn't fail and confuses me for a few seconds:

D:\git\ooui\dev (jagore/fix-nuget-copy-error)
λ lage bulid
info Lage task runner - let's make it
info � Summary
info
info Nothing has been run.
info ----------------------------------------------
info Took a total of 0.01s to complete

Similar to this change to error on circular deps, I think lage should error when undefined commands are executed to make sure pipelines fail on typos, etc.

Show build error at the bottom of the report

When a build fail, Lage produces the error and then prints a summary.
On large repos, this summary is very long and takes more than a screen. This means that for a broken build I need to start scrolling to see what the issue is.

Feature request: make --scope flag support glob

Context: I have the following packages in my repo:

A-1, A-2, B, C, D

The two following commands should be identical:
lage build --scope {A-*,B}

and
lage build --scope A-1 --scope A-2 --scope B

Breaking experience: Difference in how Lage processes dependency graph post 0.32

We saw few breaks in our pipeline after updating from 0.29.3 to 0.32.1. We have been able to reproduce the issue locally and found out that it was because of an "ambiguity" in one of our packages - which is that one of the middle verbs in a verb dependency chain was missing.

So say for dependency like test:e2e -> bundle -> build; if a package.json has test:e2e and build defined, but not bundle

Below are the steps to reproduce it. (Create a workspace with 2 packages)

lage.config.js

module.exports = {
  "pipeline": {
    "build": [ ],
    "bundle":["build"],
    "test:e2e": ["bundle"]
  }
}

packageA/package.json

{
  "name": "packageA",
  "version": "1.0.0",
  "scripts": {
    "build": "echo packageA:build",
    "test:e2e": "echo packageA:test:e2e"
  }
}

packageB/package.json

{
  "name": "packageB",
  "version": "1.0.0",
  "scripts": {
    "build": "echo packageB:build"
  }
}

Running with Lage 0.31
Notice how build ran for packageA even when there was no bundle. Even more surprisingly, build ran for packageB even when there is NO mention of test:e2e at all!!

C:\Users\gibhatna\Documents\demo> npx [email protected] test:e2e
npx: installed 395 in 30.192s
info Lage task runner - let's make it
info packageA build ▶️ start
info packageB build ▶️ start
info packageB build ✔️ done  - 1.14s
info packageA build ✔️ done  - 1.15s
info packageA test:e2e ▶️ start
info packageA test:e2e ✔️ done  - 1.02s
info 🏗 Summary
info
info [Tasks Count] success: 3, skipped: 0, incomplete: 0
info ----------------------------------------------
info Took a total of 2.46s to complete

Runing with Lage 0.32
Notice how it only runs test:e2e and does not run build even though it was present in the chain test:e2e -> bundle ( not present in package.json) -> build

C:\Users\gibhatna\Documents\workspace\test [master +5 ~0 -0 !]> npx [email protected] test:e2e
npx: installed 387 in 75.241s
info Lage task runner - let's make it
info packageA test:e2e ▶️ start
info packageA test:e2e ✔️ done  - 0.92s
info 🏗 Summary
info
info [Tasks Count] success: 1, skipped: 0, incomplete: 0
info ----------------------------------------------
info Took a total of 1.02s to complete

From what I see, Lage graph parsing has become stricter, which is why packages (like ours) which had missing/misconfigured verbs, were building fine with older versions of Lage (in some cases just luck! that interdependent packages were building at all!)

@kenotron Was this intentional? If yes, can we update documentation on this "strictness" that was introduced?

Consider using SIGTERM for terminating jobs that are running

When one task fails, all the other tasks get a SIGKILL. which leaves the children of these processes orphans, this means that the lage command is finished but there is still some processes working on the repo. Sending a SIGTERM may be more correct as processes will get a chance to propagate the SIGNAL to their children.

If process didn't die in 5s, send SIGKILL.

Use `getWorkspaceRoot` instead of `findGitRoot`

When a workspace is not in the root of a git repo, lage will fail to find the right workspace information and will fail to generate a dependency graph. To address this we need to change from using findGitRoot to getWorkspaceRoot. We've implemented a similar fix in backfill recently (PR).

Add task scope --no-cache option

There is currently a global --no-cache option.
Add an option to be able to bypass the cache for select tasks

This option could be added to the lage config or the CLI (or both)

Lage failing to bring back cached results for prepare scripts using backfill

Lage build showing some ERR entries while trying to fetch from cache using backfill approach. The overall build is passing though with success exit code. Lage is trying to use backfill to bring back cached results for the prepare scripts, but it's failing to do so (for some reason). Locally, lage is configured to use local cache (config file see below), so there shouldn't be any network requests involved. The failures are specifically happening here, in lage: lage/backfill.ts at master · microsoft/lage (github.com) (which is pointing to this part of backfill, and this is the fetch for Local storage). I don't know which part fails.

This is my config file -
const path = require("path");

module.exports = {
cacheStorageConfig: {
provider: "local",
},
logFolder: path.join(__dirname, "node_modules", ".cache", "backfill-logs"),
outputGlob: ["**/*", "!node_modules", "!package.json", "!Pods"],
logLevel: "info",
mode: "PASS",
};

Here are some logs -
info Lage task runner - let's make it
info @1js/lpc-mobile-assets prepare ▶️ start
info @1js/lpc-mobile-assets prepare ⏭️ skip - c8a07652eae3490bf584c6cc3fbb892d08931cdd
info @1js/feed-loki-rest-interface prepare ▶️ start
info @1js/feed-loki-rest-interface prepare ⏭️ skip - 0184a38f78c4fda8c634faabc05b227af04d6943
info @1js/lpp-loki-rest-interface prepare ▶️ start
info @1js/lpp-loki-rest-interface prepare ⏭️ skip - 97281c229c41ce20612607a01365e01e6a77ec51
info @1js/feed-mobile-assets prepare ▶️ start
info @1js/feed-mobile-assets prepare ⏭️ skip - 9dd1772be234afd66f4b073e8da052cbdfb34ce8
info @1js/lpp-core prepare ✔️ done - 5.75s
info @1js/lpc-models prepare ✔️ done - 5.99s
ERR! @1js/lpc-linkedin#prepare fetchBackfill
info @1js/lpc-linkedin prepare ▶️ start
ERR! @1js/lpc-teams-web#prepare fetchBackfill
info @1js/lpc-teams-web prepare ▶️ start
ERR! @1js/lpe-core#prepare fetchBackfill
info @1js/lpe-core prepare ▶️ start
ERR! @1js/nova-lpc-web#prepare fetchBackfill
info @1js/nova-lpc-web prepare ▶️ start
info @1js/lpc-linkedin prepare ✔️ done - 3.62s
info @1js/lpc-teams-web prepare ✔️ done - 1.70s
info @1js/lpe-core prepare ✔️ done - 1.71s
ERR! @1js/lpc-core#prepare fetchBackfill
info @1js/lpc-core prepare ▶️ start
info @1js/nova-lpc-web prepare ✔️ done - 4.83s
info @1js/lpc-core prepare ✔️ done - 5.94s

Should this be a warning instead of error (since the overall build is a success) and maybe with some description like : "Fetching cache failed. Will continue without cache".

Provide more info to task-scheduler so it can generate more accurate package-task graphs

Currently lage only gives a package graph and task graph separately, so task-scheduler doesn't know when some packages do not contain the tasks in the package.json.

Because of how the final combined package-task is generated, we might over-aggressively run tasks because of this missing info.

For example, if A depends on B and B depends on C:

A -> B -> C

and if only C has the task of special-C-build, when this following is called:

lage special-C-build --scope A

Nothing should be run because "A" doesn't have that task. The expected result is that nothing is run.

Caching doesn't work with Yarn v2

I've been testing lage with Yarn 2 in the microsoft/FluidFramework monorepo, and from what I can tell, lage doesn't seem to cache properly.

I don't have a minimal repro, but you can repro using my y2 branch here: https://github.com/tylerbutler/FluidFramework/tree/y2

To repro:

  1. Clone my FluidFramework fork and switch to the y2 branch.
  2. Install yarn globally using npm i -g yarn.
  3. Run yarn install.
  4. Run yarn run lage l-build.

The build will run and likely fail. Once complete run the same build command again; it will re-run everything as if nothing is cached.

Need a better name than --deps

--deps is confusing because dependent or dependencies are very SIMILAR terms that mean actually the opposite of each other. The shortened form should have been something like --consumers, etc.

Upstream and downstream terminology are also unclear which direction means what. I'm looking for some feedback here for the right name for the flag.

Bumping Lage from 0.31.0 to 0.32.0 broke our monorepo's pipeline

I am an engineer on FluentUI React Native https://github.com/microsoft/fluentui-react-native

We use page to handle our pipeline tasks, and specifically a "JS PR" CI Step. A brief overview...

We have a build-tools step that must be run before any other step. After that, we have the usual set of build,lint,test, etc. We also have a buildci step that runs all of our steps, and is meant to be used as a CI step to check our code.

Following a dependency bump from 0.31.0 to 0.32.0, two things happened:

  1. build-tools was no longer run first
  2. buildci consisted of 0 steps, so it did nothing and passed.

The combination of those meant our pipeline silently broke until we downgraded late. It's possible our config file was wrong, but we'd love more info to see if that's the case
Our config, for reference

module.exports = {
  npmClient: 'yarn',
  pipeline: {
    ['build-tools']: ['^build-tools'],
    build: ['build-tools', '^build'],
    buildci: ['build', 'test', 'depcheck', 'bundle'],
    bundle: ['build-tools', 'build'],
    clean: [],
    depcheck: ['build-tools'],
    lint: ['build-tools'],
    prettier: ['build-tools'],
    ['prettier-fix']: ['build-tools'],
    ['verify-api']: [],
    ['update-api']: [],
    test: ['build-tools', 'lint', 'build'],
  },
};

feature request: --no-bail

Scenario:

  • I changed a global config or a global dependency and I want to fix all the issues that it creates in the entire repo

Feature request:

  • If Lage had a --no-bail option, it would build all the possible tasks that don't dependent on a task that had failed. This will bring the following benefit:
    • One run a lage will show me multiple errors that I should go and fix
    • Every package is ever built only once when I run Lage multiple times. (I won't waist 9min of build by killing a 10min build process 1min away from completion)

Lage --help is incomplete

The help documentation from the CLI does not provide a full list of available commands or options. For example lage info build.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.