Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions build-tools/automation/yaml-templates/build-linux-steps.yaml
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,6 +47,11 @@ steps:
displayName: make jenkins
retryCountOnTaskFailure: 1

- template: /build-tools/automation/yaml-templates/generate-cgmanifest.yaml
parameters:
configuration: $(XA.Build.Configuration)
xaSourcePath: ${{ parameters.xaSourcePath }}

- script: make create-nupkgs CONFIGURATION=$(XA.Build.Configuration)
workingDirectory: ${{ parameters.xaSourcePath }}
displayName: make create-nupkgs
Expand Down
5 changes: 5 additions & 0 deletions build-tools/automation/yaml-templates/build-macos-steps.yaml
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,6 +50,11 @@ steps:
displayName: make jenkins
retryCountOnTaskFailure: 1

- template: /build-tools/automation/yaml-templates/generate-cgmanifest.yaml
parameters:
configuration: $(XA.Build.Configuration)
xaSourcePath: ${{ parameters.xaSourcePath }}

- script: make create-installers CONFIGURATION=$(XA.Build.Configuration) MSBUILD_ARGS='${{ parameters.makeMSBuildArgs }}'
workingDirectory: ${{ parameters.xaSourcePath }}
displayName: make create-installers
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -38,6 +38,10 @@ steps:
projects: Xamarin.Android.sln
arguments: '-c $(XA.Build.Configuration) -t:Prepare --no-restore -bl:$(System.DefaultWorkingDirectory)\bin\Build$(XA.Build.Configuration)\dotnet-build-prepare.binlog'

- template: /build-tools/automation/yaml-templates/generate-cgmanifest.yaml
parameters:
configuration: $(XA.Build.Configuration)

# Build Xamarin.Android and configure local workloads to test improved local build loop
- template: /build-tools/automation/yaml-templates/run-dotnet-preview.yaml
parameters:
Expand Down
5 changes: 5 additions & 0 deletions build-tools/automation/yaml-templates/commercial-build.yaml
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,6 +35,11 @@ steps:
workingDirectory: ${{ parameters.xaSourcePath }}
displayName: make jenkins

- template: /build-tools/automation/yaml-templates/generate-cgmanifest.yaml
parameters:
configuration: $(XA.Build.Configuration)
xaSourcePath: ${{ parameters.xaSourcePath }}

- task: CodeQL3000Finalize@0
displayName: CodeQL 3000 Finalize
condition: and(succeededOrFailed(), eq(variables['Codeql.Enabled'], 'true'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
Expand Down
109 changes: 109 additions & 0 deletions build-tools/automation/yaml-templates/generate-cgmanifest.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
# Generates bin/Build$(Configuration)/cgmanifest.json from the repository's
# git submodules. The file is consumed by the Azure DevOps Component
# Governance Detection task (auto-injected on internal pipelines by
# eng/common/core-templates/job/job.yml). This replaces the previous
# xaprepare Step_GenerateCGManifest step.

parameters:
configuration: $(XA.Build.Configuration)
xaSourcePath: $(System.DefaultWorkingDirectory)

steps:
- pwsh: |
$ErrorActionPreference = 'Stop'
Set-Location -LiteralPath '${{ parameters.xaSourcePath }}'

# Parse .gitmodules entries that live under external/ (matches the
# previous C# behavior which filtered on "submodule.external/").
$configLines = & git config --blob HEAD:.gitmodules --list
if ($LASTEXITCODE -ne 0) {
throw "git config --list failed with exit code $LASTEXITCODE"
}

$statusLines = & git submodule status
if ($LASTEXITCODE -ne 0) {
throw "git submodule status failed with exit code $LASTEXITCODE"
}

# Build a map of submodule id -> @{ Path; Url }
$prefix = 'submodule.external/'
$entries = [ordered]@{}
foreach ($line in $configLines) {
if (-not $line.StartsWith($prefix)) { continue }
$eq = $line.IndexOf('=')
if ($eq -lt 0) { continue }
$lastDot = $line.LastIndexOf('.', $eq)
if ($lastDot -lt 0) { continue }
$id = $line.Substring($prefix.Length, $lastDot - $prefix.Length)
$key = $line.Substring($lastDot, $eq - $lastDot)
$value = $line.Substring($eq + 1)
if (-not $entries.Contains($id)) {
$entries[$id] = @{ Path = $null; Url = $null }
}
if ($key -eq '.path') {
$entries[$id].Path = $value
} elseif ($key -eq '.url') {
# Strip trailing ".git" to match the previous C# behavior.
if ($value.EndsWith('.git')) {
$value = $value.Substring(0, $value.Length - 4)
}
$entries[$id].Url = $value
}
}

# Map submodule path -> commit hash via `git submodule status` output.
# Status lines are "<flag><sha> <path>[ (...)]", where <flag> is
# ' ', '-', or '+'.
$hashByPath = @{}
foreach ($line in $statusLines) {
if ([string]::IsNullOrEmpty($line)) { continue }
if ($line -match '^.([0-9a-fA-F]{40})\s+(\S+)') {
$hashByPath[$matches[2]] = $matches[1]
}
}

# Build registration objects, sorted by repositoryUrl (ordinal,
# case-insensitive) to keep the output stable across runs.
$registrations = @()
foreach ($id in $entries.Keys) {
$path = $entries[$id].Path
$url = $entries[$id].Url
if ($null -eq $path -or $null -eq $url) { continue }
$hash = ''
if ($hashByPath.ContainsKey($path)) {
$hash = $hashByPath[$path]
}
$registrations += [pscustomobject]@{ Url = $url; Hash = $hash }
}
$registrations = @($registrations |
Sort-Object -Property @{ Expression = { $_.Url.ToLowerInvariant() } } |
ForEach-Object {
[ordered]@{
component = [ordered]@{
type = 'git'
git = [ordered]@{
commitHash = $_.Hash
repositoryUrl = $_.Url
}
}
}
})

$doc = [ordered]@{
'$schema' = 'https://json.schemastore.org/component-detection-manifest.json'
version = 1
registrations = $registrations
}
$json = $doc | ConvertTo-Json -Depth 10

$outDir = Join-Path '${{ parameters.xaSourcePath }}' "bin/Build${{ parameters.configuration }}"
New-Item -ItemType Directory -Path $outDir -Force | Out-Null
$outPath = Join-Path $outDir 'cgmanifest.json'

# Write UTF-8 without BOM.
$utf8NoBom = [System.Text.UTF8Encoding]::new($false)
[System.IO.File]::WriteAllText($outPath, $json, $utf8NoBom)

Write-Host "Wrote $outPath with $($registrations.Count) registration(s)."
displayName: Generate cgmanifest.json
continueOnError: false
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,6 @@ protected override void AddSteps (Context context)
throw new ArgumentNullException (nameof (context));

Steps.Add (new Step_GenerateFiles (atBuildStart: true));
Steps.Add (new Step_GenerateCGManifest ());
}

protected override void AddEndSteps (Context context)
Expand Down
160 changes: 0 additions & 160 deletions build-tools/xaprepare/xaprepare/Steps/Step_GenerateCGManifest.cs

This file was deleted.

50 changes: 0 additions & 50 deletions build-tools/xaprepare/xaprepare/ToolRunners/GitRunner.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -95,31 +95,6 @@ public async Task<bool> Clone (string url, string destinationDirectoryPath)
return await RunGit (runner, $"clone-{dirName}");
}

public async Task<List<string>?> SubmoduleStatus (string? workingDirectory = null)
{
string runnerWorkingDirectory = DetermineRunnerWorkingDirectory (workingDirectory);

var runner = CreateGitRunner (runnerWorkingDirectory);;
runner.AddArgument ("submodule");
runner.AddArgument ("status");

var lines = new List<string> ();

bool success = await RunTool (
() => {
using (var outputSink = (OutputSink)SetupOutputSink (runner)) {
outputSink.LineCallback = (string? line) => lines.Add (line ?? String.Empty);
return runner.Run ();
}
}
);

if (!success)
return null;

return lines;
}

public async Task<bool> SubmoduleUpdate (string? workingDirectory = null, bool init = true, bool recursive = true)
{
string runnerWorkingDirectory = DetermineRunnerWorkingDirectory (workingDirectory);
Expand DownExpand Up@@ -229,31 +204,6 @@ public string GetTopCommitHash (string? workingDirectory = null, bool shortHash
return parserState.Entries;
}

public async Task<List<string>?> ConfigList (string[] fileOptions, string? workingDirectory = null)
{
var runner = CreateGitRunner (workingDirectory);
runner.AddArgument ("config");
foreach (var opt in fileOptions)
runner.AddArgument (opt);
runner.AddArgument ("--list");

var lines = new List<string> ();

bool success = await RunTool (
() => {
using (var outputSink = (OutputSink)SetupOutputSink (runner)) {
outputSink.LineCallback = (string? line) => lines.Add (line ?? String.Empty);
return runner.Run ();
}
}
);

if (!success)
return null;

return lines;
}

public async Task<bool> IsRepoUrlHttps (string workingDirectory)
{
if (!Directory.Exists (workingDirectory))
Expand Down
Loading