Skip to content

Commit b5ae764

Browse files
committed
Logon task: machine-wide for all users; remove --no-service flag
Machine-wide logon task: - Task uses GroupId S-1-5-4 (Interactive Users) instead of per-user SID - Fires for all interactive users at logon - Each user's gvfs service --mount-all reads their own LocalRepoRegistry - Remove userSid parameter from BuildTaskXml/TryRegisterOrUpdate - Remove per-user SID test (DifferentUser_Reregisters) Remove --no-service from functional tests: - Service is gone — no option to have one, flag is meaningless - Remove NoService flag, RequiresService category - Always skip service install/uninstall in test harness - Reset workflow files to upstream/master Assisted-by: Claude Sonnet 4.5 Signed-off-by: Tyrie Vella <tyrielv@gmail.com>
1 parent 141d39a commit b5ae764

12 files changed

Lines changed: 47 additions & 118 deletions

File tree

.github/workflows/build.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ jobs:
261261

262262
strategy:
263263
matrix:
264-
configuration: [ Debug, Release ]
264+
configuration: [ Release ]
265265
fail-fast: false
266266

267267
steps:

.github/workflows/functional-tests.yaml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ jobs:
6161

6262
strategy:
6363
matrix:
64-
configuration: [ Debug, Release ]
64+
configuration: [ Release ]
6565
architecture: [ x86_64, arm64 ]
66-
nr: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 10 parallel jobs to speed up the tests
66+
nr: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] # 12 parallel jobs to speed up the tests
6767
fail-fast: false # most failures are flaky tests, no need to stop the other jobs from succeeding
6868

6969
steps:
@@ -142,6 +142,17 @@ jobs:
142142
run-id: ${{ inputs.vfs_run_id || github.run_id }}
143143
github-token: ${{ secrets.vfs_token || github.token }}
144144

145+
- name: Download FastFetch drop
146+
if: steps.skip.outputs.result != 'true'
147+
continue-on-error: true
148+
uses: actions/download-artifact@v8
149+
with:
150+
name: FastFetch_${{ matrix.configuration }}
151+
path: ft
152+
repository: ${{ inputs.vfs_repository || github.repository }}
153+
run-id: ${{ inputs.vfs_run_id || github.run_id }}
154+
github-token: ${{ secrets.vfs_token || github.token }}
155+
145156
- name: ProjFS details (pre-install)
146157
if: steps.skip.outputs.result != 'true'
147158
shell: cmd
@@ -193,7 +204,7 @@ jobs:
193204
run: |
194205
SET PATH=C:\Program Files\VFS for Git;%PATH%
195206
SET GIT_TRACE2_PERF=C:\temp\git-trace2.log
196-
ft\GVFS.FunctionalTests.exe /result:TestResult.xml --ci --slice=${{ matrix.nr }},10
207+
ft\GVFS.FunctionalTests.exe /result:TestResult.xml --ci --slice=${{ matrix.nr }},12
197208
198209
- name: Upload functional test results
199210
if: always() && steps.skip.outputs.result != 'true'

.github/workflows/upgrade-tests.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626

2727
strategy:
2828
matrix:
29-
configuration: [ Debug ]
29+
configuration: [ Release ]
3030
scenario:
3131
- staging-upgrade
3232
- clean-upgrade

GVFS/GVFS.Common/LogonTaskRegistration.cs

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,25 @@
66
namespace GVFS.Common
77
{
88
/// <summary>
9-
/// Registers / updates / unregisters the per-user Windows scheduled task
10-
/// that mounts a user's registered GVFS enlistments at logon. Replaces
9+
/// Registers / updates / unregisters the machine-wide Windows scheduled task
10+
/// that mounts registered GVFS enlistments at logon for each interactive user. Replaces
1111
/// the role of <c>GVFS.Service</c>'s session-change-driven AutoMount in
1212
/// the user-level install model.
1313
/// </summary>
1414
/// <remarks>
1515
/// <para>
16-
/// The task is registered at <c>\GVFS\AutoMount</c>, scoped to a single
17-
/// user (the user's SID is baked into the task's principal and trigger),
18-
/// runs at user logon with the user's interactive token, and executes
19-
/// <c>gvfs.exe service --mount-all</c>. The mount-all verb already
20-
/// reads the user's registered repos (via <see cref="LocalRepoRegistry"/>
21-
/// fallback when the service is unavailable) and mounts each one.
16+
/// The task is registered at <c>\GVFS\AutoMount</c>, scoped to all
17+
/// interactive users (GroupId S-1-5-4), runs at user logon with the
18+
/// user's interactive token, and executes <c>gvfs.exe service --mount-all</c>.
19+
/// The mount-all verb reads the user's registered repos (via <see cref="LocalRepoRegistry"/>)
20+
/// and mounts each one.
2221
/// </para>
2322
/// <para>
2423
/// Drift detection works via a content-hash marker embedded in the
2524
/// task's Description field
2625
/// (<c>[gvfs-logon-task-hash=XXXXXXXXXXXXXXXX]</c>). The hash covers the
2726
/// XML template <em>with placeholders still in place</em>, so it is
28-
/// stable across re-substitutions with different user SIDs or gvfs.exe
27+
/// stable across re-substitutions with different gvfs.exe
2928
/// paths -- only template content changes (a code change to the
3029
/// template constant) bump the hash. <see cref="IsCurrent"/> queries
3130
/// the registered task XML, extracts the marker, and compares against
@@ -45,7 +44,6 @@ public class LogonTaskRegistration
4544
public const string FullTaskPath = @"\GVFS\AutoMount";
4645

4746
public const string GvfsPathPlaceholder = "__GVFS_PATH__";
48-
public const string UserIdPlaceholder = "__USER_ID__";
4947
public const string TaskHashPlaceholder = "__TASK_HASH__";
5048

5149
public const string HashMarkerPrefix = "[gvfs-logon-task-hash=";
@@ -55,9 +53,6 @@ public class LogonTaskRegistration
5553
/// Task XML template. Placeholders:
5654
/// <list type="bullet">
5755
/// <item><c>__GVFS_PATH__</c> -- absolute path to gvfs.exe</item>
58-
/// <item><c>__USER_ID__</c> -- the user's SID (must be the same one
59-
/// the principal runs as, so the logon trigger fires for the
60-
/// right user)</item>
6156
/// <item><c>__TASK_HASH__</c> -- content hash of this template,
6257
/// inserted into the Description for drift detection</item>
6358
/// </list>
@@ -69,19 +64,17 @@ public class LogonTaskRegistration
6964
<Task version=""1.4"" xmlns=""http://schemas.microsoft.com/windows/2004/02/mit/task"">
7065
<RegistrationInfo>
7166
<Author>GVFS</Author>
72-
<Description>Mounts the user's registered GVFS enlistments at logon. Required by VFS for Git in the user-level install model. [gvfs-logon-task-hash=__TASK_HASH__]</Description>
67+
<Description>Mounts registered GVFS enlistments at logon for each interactive user. Required by VFS for Git. [gvfs-logon-task-hash=__TASK_HASH__]</Description>
7368
<URI>\GVFS\AutoMount</URI>
7469
</RegistrationInfo>
7570
<Triggers>
7671
<LogonTrigger>
7772
<Enabled>true</Enabled>
78-
<UserId>__USER_ID__</UserId>
7973
</LogonTrigger>
8074
</Triggers>
8175
<Principals>
8276
<Principal id=""Author"">
83-
<UserId>__USER_ID__</UserId>
84-
<LogonType>InteractiveToken</LogonType>
77+
<GroupId>S-1-5-4</GroupId>
8578
<RunLevel>LeastPrivilege</RunLevel>
8679
</Principal>
8780
</Principals>
@@ -145,14 +138,12 @@ public static LogonTaskRegistration CreateForCurrentPlatform(ITracer tracer)
145138
/// <summary>
146139
/// Substitute placeholders to produce a registerable task XML.
147140
/// </summary>
148-
public static string BuildTaskXml(string gvfsExePath, string userSid)
141+
public static string BuildTaskXml(string gvfsExePath)
149142
{
150143
ArgumentException.ThrowIfNullOrEmpty(gvfsExePath);
151-
ArgumentException.ThrowIfNullOrEmpty(userSid);
152144

153145
return XmlTemplate
154146
.Replace(GvfsPathPlaceholder, gvfsExePath)
155-
.Replace(UserIdPlaceholder, userSid)
156147
.Replace(TaskHashPlaceholder, TemplateHash);
157148
}
158149

@@ -208,31 +199,29 @@ public bool IsCurrent()
208199
}
209200

210201
/// <summary>
211-
/// Register the logon task with the given gvfs.exe path and user
212-
/// SID, overwriting any existing registration. Idempotent: when
202+
/// Register the logon task with the given gvfs.exe path,
203+
/// overwriting any existing registration. Idempotent: when
213204
/// the registered task already matches the intended XML (same
214205
/// hash, same args), this is a fast no-op.
215206
/// </summary>
216-
public bool TryRegisterOrUpdate(string gvfsExePath, string userSid, out string errorMessage)
207+
public bool TryRegisterOrUpdate(string gvfsExePath, out string errorMessage)
217208
{
218209
ArgumentException.ThrowIfNullOrEmpty(gvfsExePath);
219-
ArgumentException.ThrowIfNullOrEmpty(userSid);
220210

221211
if (this.IsCurrent())
222212
{
223213
// Still verify args are right; the hash covers the template
224214
// structure but not the substituted gvfs.exe path. Re-query
225215
// and check the action command.
226216
if (this.invoker.TryQueryXml(FullTaskPath, out string existingXml, out _) &&
227-
existingXml.Contains(gvfsExePath, StringComparison.Ordinal) &&
228-
existingXml.Contains($"<UserId>{userSid}</UserId>", StringComparison.Ordinal))
217+
existingXml.Contains(gvfsExePath, StringComparison.Ordinal))
229218
{
230219
errorMessage = string.Empty;
231220
return true;
232221
}
233222
}
234223

235-
string xml = BuildTaskXml(gvfsExePath, userSid);
224+
string xml = BuildTaskXml(gvfsExePath);
236225
return this.invoker.TryRegisterFromXml(FullTaskPath, xml, out errorMessage);
237226
}
238227

GVFS/GVFS.FunctionalTests/Categories.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@ public static class Categories
66
public const string FastFetch = "FastFetch";
77
public const string GitCommands = "GitCommands";
88
public const string NeedsReactionInCI = "NeedsReactionInCI";
9-
public const string RequiresService = "RequiresService";
109
}
1110
}

GVFS/GVFS.FunctionalTests/GVFSTestConfig.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ public static class GVFSTestConfig
1818

1919
public static bool IsDevMode { get; set; }
2020

21-
public static bool NoService { get; set; }
22-
2321
public static string PathToGVFS
2422
{
2523
get

GVFS/GVFS.FunctionalTests/GlobalSetup.cs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,6 @@ public void RunBeforeAnyTests()
1818
[OneTimeTearDown]
1919
public void RunAfterAllTests()
2020
{
21-
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
22-
{
23-
if (!GVFSTestConfig.NoService)
24-
{
25-
string serviceLogFolder = Path.Combine(
26-
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
27-
"GVFS",
28-
GVFSServiceProcess.TestServiceName,
29-
"Logs");
30-
31-
Console.WriteLine("GVFS.Service logs at '{0}' attached below.\n\n", serviceLogFolder);
32-
foreach (string filename in TestResultsHelper.GetAllFilesInDirectory(serviceLogFolder))
33-
{
34-
TestResultsHelper.OutputFileContents(filename);
35-
}
36-
37-
GVFSServiceProcess.UninstallService();
38-
}
39-
}
40-
4121
PrintTestCaseStats.PrintRunTimeStats();
4222
}
4323
}

GVFS/GVFS.FunctionalTests/Program.cs

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -48,22 +48,11 @@ public static void Main(string[] args)
4848
GVFSTestConfig.ReplaceInboxProjFS = true;
4949
}
5050

51-
if (runner.HasCustomArg("--no-service"))
52-
{
53-
Console.WriteLine("Running in no-service mode (user-level install model)");
54-
GVFSTestConfig.NoService = true;
55-
}
56-
5751
GVFSTestConfig.LocalCacheRoot = runner.GetCustomArgWithParam("--shared-gvfs-cache-root");
5852

5953
HashSet<string> includeCategories = new HashSet<string>();
6054
HashSet<string> excludeCategories = new HashSet<string>();
6155

62-
if (GVFSTestConfig.NoService)
63-
{
64-
excludeCategories.Add(Categories.RequiresService);
65-
}
66-
6756
if (runner.HasCustomArg("--full-suite"))
6857
{
6958
Console.WriteLine("Running the full suite of tests");
@@ -162,19 +151,8 @@ private static void RunBeforeAnyTests()
162151
ProjFSFilterInstaller.ReplaceInboxProjFS();
163152
}
164153

165-
if (!GVFSTestConfig.NoService)
166-
{
167-
Console.WriteLine("[CI-DEBUG] Installing service...");
168-
Console.Out.Flush();
169-
GVFSServiceProcess.InstallService();
170-
Console.WriteLine("[CI-DEBUG] Service installed successfully");
171-
Console.Out.Flush();
172-
}
173-
else
174-
{
175-
Console.WriteLine("[CI-DEBUG] Skipping service install (--no-service mode)");
176-
Console.Out.Flush();
177-
}
154+
Console.WriteLine("[CI-DEBUG] Skipping service install (service removed)");
155+
Console.Out.Flush();
178156

179157
string serviceProgramDataDir = GVFSPlatform.Instance.GetSecureDataRootForGVFSComponent(
180158
GVFSConstants.Service.ServiceName);

GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/GVFSUpgradeReminderTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ namespace GVFS.FunctionalTests.Tests.EnlistmentPerFixture
1313
[TestFixture]
1414
[NonParallelizable]
1515
[Category(Categories.ExtraCoverage)]
16-
[Category(Categories.RequiresService)]
1716
public class UpgradeReminderTests : TestsWithEnlistmentPerFixture
1817
{
1918
private const string HighestAvailableVersionFileName = "HighestAvailableVersion";

GVFS/GVFS.FunctionalTests/Tests/MultiEnlistmentTests/ServiceVerbTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ namespace GVFS.FunctionalTests.Tests.MultiEnlistmentTests
77
[TestFixture]
88
[NonParallelizable]
99
[Category(Categories.ExtraCoverage)]
10-
[Category(Categories.RequiresService)]
1110
public class ServiceVerbTests : TestsWithMultiEnlistment
1211
{
1312
private static readonly string[] EmptyRepoList = new string[] { };

0 commit comments

Comments
 (0)