[▲ Vercel Community](/) · [Categories](/categories) · [Latest](/latest) · [Top](/top) · [Live](/live) [Help](/c/help/9) # How can I ignore a build step based on git information (e.g. branch name) without Vercel cloning the repo? 295 views · 10 likes · 8 posts Michael Schaufelberger (@michaelschufi) · 2024-07-22 ### Summary Hi :) To reduce the waiting time for the builds in our monorepo, we're using an ignore build step script to not build a project if it's not needed. However, Vercel still spends about 15 seconds for each project in the monorepo cloning and running the ignore build step script, because the codebase grew in size. We would like to reduce those wait times by not cloning the repo on every check. Because 95% of the time, the cloning would not be necessary since we can check the commit metadata (e.g. branch name) to a environment variable to see if we actually need to build a project. So no code is required (besides the script atm). **Note** We want to reduce the time spent cloning, since that takes ~10-15s. So, depending on which project comes first, we have to wait `numberOfProjectsBeforeTheCorrectOne * 15s` for the intended build to start. Because every project will clone the repo first, and only afterwards execute the script. We are using Turborepo for our monorepo atm. ### Steps to Reproduce Our current script: ```ts /* eslint-disable no-console */ const { VERCEL_GIT_COMMIT_REF, BRANCH_PREFIX } = process.env; console.log(`BRANCH_PREFIX: ${BRANCH_PREFIX}`); console.log(`VERCEL_GIT_COMMIT_REF: ${VERCEL_GIT_COMMIT_REF}`); if ( VERCEL_GIT_COMMIT_REF == 'dev' || VERCEL_GIT_COMMIT_REF == 'main' || VERCEL_GIT_COMMIT_REF.startsWith(`${BRANCH_PREFIX}/`) ) { // Proceed with the build console.log('✅ - Build can proceed'); process.exit(1); } // Don't build console.log('🛑 - Build cancelled'); process.exit(0); ``` Amy Egan (@amyegan) · 2024-07-23 · ♥ 3 Hey @michaelschufi! Funny you should bring this up. We just released an update to make it easier to skip unchanged projects from monorepos. :smile: https://vercel.com/changelog/automatically-skip-unnecessary-deployments-in-monorepos Otherwise, [Ignored Build Step](https://vercel.com/docs/projects/overview#ignore-build-step-on-redeploy) or a [custom workflow](https://vercel.com/guides/using-vercel-cli-for-custom-workflows) are your best options if more customization is needed. Michael Schaufelberger (@michaelschufi) · 2024-07-24 This sounds like an interesting feature. :smiley: Thanks! However, this will still build feature branches that update a specific internal dependency (e.g. adding a utility to the shared internal utility package), correct? There is no way to exclude such builds until there's a PR or until a branch is merged, correct? What happens if we skip such a build after a feature branch has updated a dependency? Will the next commit of the same feature branch (that doesn't alter internal packages compared to the first commit) try to build again? Mehul Kar (@mehulkar) · 2024-07-24 · ♥ 4 > However, this will still build feature branches that update a specific internal dependency (e.g. adding a utility to the shared internal utility package), correct? If an internal dependency is *used* by your Vercel project, it will create a deployment, yes. If the internal dependency does not appear in the root package.json or your project's package.json, it would not create a deployment. > Will the next commit of the same feature branch (that doesn’t alter internal packages compared to the first commit) try to build again? The feature is based on the `push` event from Github. So if the `push` event contains 5 commits, we'll use the contents of those 5 commits to determine whether your project changed. If those 5 commits include an internal dependency that affects your project, it will build. Michael Schaufelberger (@michaelschufi) · 2024-07-25 Thank you, that sounds great. Sorry, but I still have a few more things I'd like to clarify. This feels like magic :sweat_smile: **Subsequent skips** > The feature is based on the `push` event from Github. So if the `push` event contains 5 commits, we’ll use the contents of those 5 commits to determine whether your project changed. If those 5 commits include an internal dependency that affects your project, it will build. What I don't quite understand. What is taken into account when you *determine whether your project changed*. Will you compare it to the last successful build, or any build that has been run? Say we have a monorepo with an internal package `packages/utils` and app packages `apps/web` and `apps/docs` that have `utils` in the dependencies inside `package.json` 3 commits: 1. initial (sets up all packages) 2. branching for a docs feature branch a. `utils` update b. code update in the `docs` package 3. Feature branch gets merged Assuming the initial commit builds the project successfully, the build trigger behaviour of the `web` app is the following (when pushing after each commit) - Commit `2a` will trigger a build. The utils package is a dependency and its source code has changed. - Commit `2b` will *not* trigger a build, the `web` app is unaffected - Commit `3` will trigger a build, since the merge commit includes the updates to `utils` and Do I understand this correctly? Now, what if we were to ignore commit `2a` in an ignore build step (since it's a feature branch, we only want to build it later when a PR is open). Will commit `2b` trigger an update or not? Compared to the last successful build (the initial commit) the `utils` package is different. **Triggering a build on PR** A question that came to mind writing this. If all the commits in the feature branch are ignored after the commit `2a` - what's the best way to trigger a build when a PR is opened so it doesn't get skipped? In order to check if the changes inside `utils` are affecting `web` in an unintended way. Previously, we could potentially check this inside the ignore build step script. But now, if the script is not even triggered, that's not an option, correct? I'm not up-to-date with how GitHub's webhooks handle commits that are in an open PR - maybe they are handled differently? Mehul Kar (@mehulkar) · 2024-07-29 · ♥ 1 [quote="michaelschufi, post:7, topic:259"] don’t quite understand. What is taken into account when you *determine whether your project changed*. Will you compare it to the last successful build, or any build that has been run? [/quote] We look at files changed in the commit, and determine what packages in your monorepo are affected by those files changed. Then we match the paths of those packages to the rootDirectory of associated Vercel projects to determine which projects need to be redeployed. [quote="michaelschufi, post:7, topic:259"] Now, what if we were to ignore commit `2a` in an ignore build step (since it’s a feature branch, we only want to build it later when a PR is open). Will commit `2b` trigger an update or not? Compared to the last successful build (the initial commit) the `utils` package is different. [/quote] Assuming you did a `git push` for `2a`, `2b` would probably *not* deploy web, becuase 2b is compared to 2a (the last previous deploy). This is the behavior today, but we are open to feedback on how it should work. [quote="michaelschufi, post:7, topic:259"] If all the commits in the feature branch are ignored after the commit `2a` - what’s the best way to trigger a build when a PR is opened so it doesn’t get skipped? [/quote] Curious, what's your logic for skipping the deployment in the Ignored Build Step? I ask because I'm not sure how you can customize behavior on `push`, and then have something else happen when the PR is opened. To answer your question more directly, some ways to do that right now (assuming it's possible to end up in the situation you describe), is to - push up another commit (not great, but then you have some changes the can trigger a deploy) - on the canceled build in the vercel.com UI, use the Redeploy button to manually trigger a deployment. [quote="michaelschufi, post:7, topic:259"] In order to check if the changes inside `utils` are affecting `web` in an unintended way. Previously, we could potentially check this inside the ignore build step script. But now, if the script is not even triggered, that’s not an option, correct? [/quote] You can opt out of the feature and continue using the Ignored Build Step if you want to know more granularly whether `utils/` affects `web`. We did consider implementing file tracing to do this, but decided not to in the first iteration. Using the package dependency graph naively covers a bulk of the use cases. If your `utils` pacakge is fairly large and not all changes affect the upstream apps that use it, it may also be a good signal that `utils` should get split up! Michael Schaufelberger (@michaelschufi) · 2024-07-29 Thank you for all the answers! :pray: [quote="mehulkar, post:10, topic:259"] Assuming you did a `git push` for `2a`, `2b` would probably *not* deploy web, becuase 2b is compared to 2a (the last previous deploy). This is the behavior today, but we are open to feedback on how it should work. [/quote] Okay, so as long as there's a `git push` of `2a`, `2b` will probably be skipped - regardless of the build outcome of `2a` (canceled by user/build step ignore/error)? I would also expect this behaviour (always comparing to the latest build that's in the Deployments list, including the cancelled ones). [quote="mehulkar, post:10, topic:259"] Curious, what’s your logic for skipping the deployment in the Ignored Build Step? I ask because I’m not sure how you can customize behavior on `push`, and then have something else happen when the PR is opened. [/quote] The idea would be to build projects not involved in the feature branch as late as possible. If, for example, `2a` is reverted before opening the PR, `web` will never have deployed. But if the PR opens and `2a` isn't reverted, `web` should be built before the merge happens. The logic itself is so far: Given a branch in the format `projectBranchName/feature-name` if the word before the `/` does not match an env variable, we skip the build. (see also my OP) [quote="mehulkar, post:10, topic:259"] - on the canceled build in the [vercel.com](http://vercel.com) UI, use the Redeploy button to manually trigger a deployment. [/quote] If there's always a cancelled build when the build is skipped by this feature, I think that would be sufficient. Even if it requires a manual interaction. Although, we would have to press the button for each affected project... :thinking: (That's why we probably won't use the previously mentioned ignore build step strategy anymore.) [quote="mehulkar, post:10, topic:259"] If your `utils` pacakge is fairly large and not all changes affect the upstream apps that use it, it may also be a good signal that `utils` should get split up! [/quote] Meaning, the whole `utils` package should get split up and not just its exported modules inside it? I assume this would be possible only with file tracing, correct? **Looks nice!** I think we will just have to try it out. I'll gladly give more feedback later! Mehul Kar (@mehulkar) · 2024-07-29 · ♥ 2 [quote="michaelschufi, post:11, topic:259"] Meaning, the whole `utils` package should get split up and not just its exported modules inside it? [/quote] yes exactly. In theory at least. I know it's very common for large `util/` packages in practice though. [quote="michaelschufi, post:11, topic:259"] If there’s always a cancelled build when the build is skipped by this feature, I think that would be sufficient. [/quote] :+1: [quote="michaelschufi, post:11, topic:259"] Although, we would have to press the button for each affected project [/quote] yeah, depending on the number of projects you have this isn't great.