Skip to content

Fix Touch race condition on first run with parallel MSBuild nodes#168

Merged
alirezanet merged 1 commit intoalirezanet:masterfrom
MattKotsenas:bugfix/target-first-install
Mar 13, 2026
Merged

Fix Touch race condition on first run with parallel MSBuild nodes#168
alirezanet merged 1 commit intoalirezanet:masterfrom
MattKotsenas:bugfix/target-first-install

Conversation

@MattKotsenas
Copy link
Copy Markdown
Contributor

@MattKotsenas MattKotsenas commented Mar 12, 2026

Description

When multiple MSBuild nodes run dotnet husky install concurrently on first checkout (e.g., via Directory.Build.targets), the mutex losers skip the install but the Touch task still tries to create install.stamp in the .husky/_/ directory. Since that directory hasn't been created yet (the winner is still working), this fails with:

error MSB3371: The file ".husky/_/install.stamp" cannot be created.
Could not find a part of the path '.husky/_/install.stamp'.

Who's impacted:

  • Users who adopted the new incremental target (v0.9.0 via dotnet husky attach or docs snippet)
  • In a solution with multiple projects (where MSBuild runs parallel restore)
  • Only on first build after a fresh checkout (before .husky/_/ exists)

Not impacted:

  • Users with the old target (no Touch task)
  • Single-project solutions (no parallelism)
  • Any build after the first successful one (directory exists, Touch condition passes)

Fixes #155

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Checklist

  • I have performed a self-review of my code
  • I have added tests that prove my fix is effective or that my feature works
  • I have made corresponding changes to the documentation
  • I have commented my code, particularly in hard-to-understand areas
  • New and existing unit tests pass locally with my changes
  • I did test corresponding changes on Windows
  • I did test corresponding changes on Linux
  • I did test corresponding changes on Mac

When multiple MSBuild nodes run concurrently on first checkout, the
mutex losers skip the install but the Touch task still tried to create
install.stamp in the not-yet-created .husky/_/ directory, causing
MSB3371 errors.

Fix: capture the ExitCode from the install Exec and condition Touch
on both exit code 0 and the .husky/_/ directory existing. Losers
skip Touch entirely - no premature stamp, no error.
@what-the-diff
Copy link
Copy Markdown

what-the-diff bot commented Mar 12, 2026

PR Summary

  • Update on automated checks for Touch element
    The automate.md file has been revised to include a check for the existence of a certain directory (.husky/_) before running the Touch element. It provides additional safety measures to ensure all necessary prerequisites are met before the execution of the task.

  • New condition and attributes added to submodule handling
    Changes in submodules.md include the newly added condition for the Touch element that was added to automate.md. Moreover, inputs and outputs attributes have been defined for the husky Target to clearly segregate incoming data and resultant findings.

  • Availability check of directory before setting conditions
    In AttachCommand.cs, conditions for running the Touch element are now assigned based on the existence of the directory (.husky/). This assures that the command will only be activated if the vital directory is present.

  • Changes in the sequencing of the Husky Target
    The update in Husky.csproj modifies the sequence of when the husky Target is called, moving it from before the targets to after them. The requirement of the existence of .husky/_ was also applied for Touch element validation, making sure that the task will be performed only if the directory is available.

  • Test adjustments to verify condition setting
    With the modifications in AttachCommandTests.cs, tests have been adjusted to confirm that the condition attribute for the Touch element correctly verifies the existence of the directory before running. This helps in maintaining code accuracy and efficacy.

@MattKotsenas
Copy link
Copy Markdown
Contributor Author

/cc @alirezanet, I found a bug in the new target (sorry 😥). It's unlikely to impact many existing users, but given that we just shipped it, wanted to flag for fast follow up.

Let me know if there's anything I can do to help.

Copy link
Copy Markdown
Owner

@alirezanet alirezanet left a comment

Choose a reason for hiding this comment

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

Thanks for testing it
LGTM, but now I'm thinking it might be hard for users to adjust the file paths correctly if they want to do it manually.
if you had time please investigate to see if there is anyway to reuese the WorkingDirectory somehow in other elements. what I'm thinking is to define the husky working directory once and reuse it for all of these paths. so we don't end up with multiple paths like ../../.husky/_
but yeah if you think is not possible or it is time consuming is better to merge this PR first and investigate later.

@MattKotsenas
Copy link
Copy Markdown
Contributor Author

If it's ok with you, want to merge this and I'll follow up?

The reason I didn't do it initially is because it's also in the Inputs and Outputs, so I can't define any base property inside the target to reuse.

@alirezanet alirezanet merged commit df7dd09 into alirezanet:master Mar 13, 2026
1 check passed
renovate bot added a commit to psimsa/github-actions-autoscaler that referenced this pull request Mar 13, 2026
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [husky](https://redirect.github.com/alirezanet/husky.net) | `0.9.0` →
`0.9.1` |
![age](https://developer.mend.io/api/mc/badges/age/nuget/husky/0.9.1?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/nuget/husky/0.9.0/0.9.1?slim=true)
|

---

### Release Notes

<details>
<summary>alirezanet/husky.net (husky)</summary>

###
[`v0.9.1`](https://redirect.github.com/alirezanet/Husky.Net/releases/tag/v0.9.1)

[Compare
Source](https://redirect.github.com/alirezanet/husky.net/compare/v0.9.0...v0.9.1)

#### What's Changed

- Fix install command race condition on first run with parallel MSBuild
nodes by
[@&#8203;MattKotsenas](https://redirect.github.com/MattKotsenas) in
[alirezanet/Husky.Net#168](https://redirect.github.com/alirezanet/Husky.Net/pull/168)

**Full Changelog**:
<alirezanet/Husky.Net@v0.9.0...v0.9.1>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/psimsa/github-actions-autoscaler).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My42Ni40IiwidXBkYXRlZEluVmVyIjoiNDMuNjYuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
WarperSan pushed a commit to WarperSan/ThunderPipe that referenced this pull request Mar 30, 2026
Updated [husky](https://github.com/alirezanet/husky.net) from 0.8.0 to
0.9.1.

<details>
<summary>Release notes</summary>

_Sourced from [husky's
releases](https://github.com/alirezanet/husky.net/releases)._

## 0.9.1

## What's Changed
* Fix install command race condition on first run with parallel MSBuild
nodes by @​MattKotsenas in
alirezanet/Husky.Net#168


**Full Changelog**:
alirezanet/Husky.Net@v0.9.0...v0.9.1

## 0.9.0

## What's Changed
* remove net6.0/net7.0 since out of support by @​WeihanLi in
alirezanet/Husky.Net#135
* fix: update regex pattern to allow breaking commits by @​joaoopereira
in alirezanet/Husky.Net#153
* Fix parallel install mutex bug and support incremental build by
@​MattKotsenas in alirezanet/Husky.Net#159
* fix: handle file paths with spaces in git commands in
alirezanet/Husky.Net#156
* feat: add `staged` property to custom variables for re-staging support
in alirezanet/Husky.Net#163
* feat: support variables in include/exclude glob patterns in
alirezanet/Husky.Net#161
* fix: use AfterTargets="Restore" to support NuGet credential helpers
for private feeds in alirezanet/Husky.Net#162

## New Contributors
* @​joaoopereira made their first contribution in
alirezanet/Husky.Net#153
* @​MattKotsenas made their first contribution in
alirezanet/Husky.Net#159

**Full Changelog**:
alirezanet/Husky.Net@v0.8.0...v0.9.0

Commits viewable in [compare
view](alirezanet/Husky.Net@v0.8.0...v0.9.1).
</details>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=husky&package-manager=nuget&previous-version=0.8.0&new-version=0.9.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Guide for automating installation causes unnecessary work to be done when applied to multiple projects

2 participants