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
14 changes: 14 additions & 0 deletions .github/BuildHelpers/BuildHelpers.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Bullseye" Version="6.1.0" />
<PackageReference Include="SimpleExec" Version="12.1.0" />
</ItemGroup>

</Project>
92 changes: 92 additions & 0 deletions .github/BuildHelpers/Targets.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using static Bullseye.Targets;
using static SimpleExec.Command;

namespace BuildHelpers;

/// <summary>
/// Registers build targets for per-lib build scripts.
/// </summary>
public static class Targets
{
private static readonly Lazy<string> RepoRoot = new(FindRoot);

public const string Restore = "restore";
public const string Build = "build";
public const string Clean = "clean";
public const string Pack = "pack";
public const string Test = "test";

private const string Default = "default";

/// <summary>
/// Registers all shared targets parameterized by the lib's solution filter path.
/// </summary>
/// <param name="slnfPath">
/// Repo-relative path to the lib's solution filter
/// (e.g. <c>signatures/signatures.slnf</c>).
/// </param>
/// <param name="packProjectPath">
/// Repo-relative path to the lib's packable src project
/// (e.g. <c>signatures/src/Http.HttpSignatures</c>).
/// </param>
public static void SharedTargets(string slnfPath, string packProjectPath)
{
ArgumentNullException.ThrowIfNull(slnfPath);
ArgumentNullException.ThrowIfNull(packProjectPath);

var libDir = slnfPath.Split('/')[0];

Target(Restore, () =>
RunAsync("dotnet", $"restore {slnfPath}", RepoRoot.Value));

Target(Build, dependsOn: [Restore], () =>
RunAsync("dotnet", $"build {slnfPath} --no-restore -c Release", RepoRoot.Value));

Target(Clean, () =>
RunAsync("dotnet", $"clean {slnfPath}", RepoRoot.Value));

Target(Pack, dependsOn: [Build], () =>
RunAsync(
"dotnet",
$"pack {packProjectPath} --no-build -c Release -o {libDir}/artifacts",
RepoRoot.Value));
}

/// <summary>
/// Registers a test target that runs <c>dotnet test</c> on a test project with standard options.
/// </summary>
/// <param name="targetName">The target name (e.g. <c>"test"</c>).</param>
/// <param name="testProjectPath">
/// Repo-relative path to the test project
/// (e.g. <c>"signatures/test/Http.HttpSignatures.Tests"</c>).
/// </param>
public static void TestTarget(string targetName, string testProjectPath) =>
Target(targetName, dependsOn: [Restore], () =>
RunAsync(
"dotnet",
$"test --project {testProjectPath} -c Release --no-restore --report-xunit-trx " +
$"--report-xunit-trx-filename {testProjectPath.Replace('/', '-')}-tests.trx",
RepoRoot.Value));
Comment thread
damianh marked this conversation as resolved.

public static void DefaultTarget(IEnumerable<string> dependsOn) =>
Target(Default, dependsOn);

public static Task RunTargetsAndExitAsync(IEnumerable<string> args) =>
Bullseye.Targets.RunTargetsAndExitAsync(args, messageOnly: ex => ex is SimpleExec.ExitCodeException);

private static string FindRoot()
{
var root = Directory.GetCurrentDirectory();

// Repositories have a .git folder, worktrees have a .git file, so check for both.
while (!Directory.Exists(Path.Combine(root, ".git")) && !File.Exists(Path.Combine(root, ".git")))
{
root = Directory.GetParent(root) is { } parent
? parent.FullName
: throw new InvalidOperationException(
"Could not find repository root (no .git directory or file found)");
}

return root;
}
}
71 changes: 71 additions & 0 deletions .github/workflows/ci-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: ci-template

on:
workflow_call:
inputs:
product:
description: "Lib folder name (e.g. signatures, structured-field-values)"
required: true
type: string
test-targets:
description: 'JSON array of build.cs test targets (e.g. ["test"]). Empty array or "[]" to skip.'
required: false
type: string
default: '["test"]'
os-matrix:
description: 'JSON array of OS runners for the test job. Defaults to ubuntu only.'
required: false
type: string
default: '["ubuntu-latest"]'

env:
DOTNET_NOLOGO: true
DOTNET_CLI_TELEMETRY_OPTOUT: true

jobs:
build:
name: Build
runs-on: ubuntu-latest
permissions:
contents: read
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Build
run: dotnet run ${{ inputs.product }}/build.cs -- build

test:
name: "Test: ${{ matrix.target }} (${{ matrix.os }})"
if: inputs.test-targets != '[]'
Comment thread
damianh marked this conversation as resolved.
runs-on: ${{ matrix.os }}
permissions:
contents: read
strategy:
matrix:
target: ${{ fromJson(inputs.test-targets) }}
os: ${{ fromJson(inputs.os-matrix) }}
fail-fast: false
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Test
run: dotnet run ${{ inputs.product }}/build.cs -- ${{ matrix.target }}
- name: Test report
if: success() || failure()
uses: phoenix-actions/test-reporting@f957cd93fc2d848d556fa0d03c57bc79127b6b5e
with:
name: "${{ inputs.product }}: ${{ matrix.target }} (${{ matrix.os }})"
path: "**/*-tests.trx"
reporter: dotnet-trx
output-to: step-summary
fail-on-error: true
108 changes: 0 additions & 108 deletions .github/workflows/ci.yml

This file was deleted.

34 changes: 34 additions & 0 deletions .github/workflows/file-distributed-cache-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: file-distributed-cache/ci

on:
workflow_dispatch:
push:
branches:
- main
- '**'
paths:
- .github/BuildHelpers/**
- .github/workflows/file-distributed-cache-ci.yml
- .github/workflows/ci-template.yml
- file-distributed-cache/**
- .editorconfig
- Directory.Build.props
- global.json
- http-lib.slnx
pull_request:
paths:
- .github/BuildHelpers/**
- .github/workflows/file-distributed-cache-ci.yml
- .github/workflows/ci-template.yml
- file-distributed-cache/**
- .editorconfig
- Directory.Build.props
- global.json
- http-lib.slnx

jobs:
build:
uses: ./.github/workflows/ci-template.yml
with:
product: file-distributed-cache
test-targets: '["test"]'
20 changes: 20 additions & 0 deletions .github/workflows/file-distributed-cache-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: file-distributed-cache/release

on:
workflow_dispatch:
inputs:
version:
description: 'Version number (x.y.z or x.y.z-prerelease.1)'
required: true
type: string

jobs:
release:
uses: ./.github/workflows/release-template.yml
with:
product: file-distributed-cache
package: DamianH.FileDistributedCache
tag-prefix: fdc-v
version: ${{ inputs.version }}
secrets:
NUGET_ORG_APIKEY: ${{ secrets.NUGET_ORG_APIKEY }}
Loading
Loading