Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Workflows #15

Merged
merged 47 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
e19ccae
add coverage test
cklutz Oct 10, 2024
9aa1586
fixes
cklutz Oct 10, 2024
d3af43b
fixes
cklutz Oct 10, 2024
255268c
fixes
cklutz Oct 10, 2024
8f91e74
fixes
cklutz Oct 10, 2024
38c1a90
fixes
cklutz Oct 10, 2024
8a419af
fixes
cklutz Oct 10, 2024
a7ce540
fixes
cklutz Oct 10, 2024
5942a25
fixes
cklutz Oct 10, 2024
6277683
fixes
cklutz Oct 10, 2024
8f5e508
fixes
cklutz Oct 10, 2024
c02d1f1
fixes
cklutz Oct 10, 2024
164386e
enable dotnet caching
cklutz Oct 10, 2024
bf60398
disable dotnet caching
cklutz Oct 10, 2024
6cb2b4d
disable dotnet caching
cklutz Oct 10, 2024
31236f4
disable dotnet caching
cklutz Oct 10, 2024
8a67c02
goofing around
cklutz Oct 10, 2024
0c6de3e
goofing around
cklutz Oct 10, 2024
1b45805
goofing around
cklutz Oct 10, 2024
a3bfe67
goofing around
cklutz Oct 10, 2024
9dfbad5
goofing around
cklutz Oct 10, 2024
be522fe
goofing around
cklutz Oct 10, 2024
d474dc5
goofing around
cklutz Oct 10, 2024
3678132
goofing around
cklutz Oct 10, 2024
265efc0
goofing around
cklutz Oct 10, 2024
0d11169
goofing around
cklutz Oct 10, 2024
e9bf034
goofing around
cklutz Oct 10, 2024
943d1e5
goofing around
cklutz Oct 11, 2024
2a58b31
goofing around
cklutz Oct 11, 2024
2a3c84d
goofing around
cklutz Oct 11, 2024
9631e17
goofing around
cklutz Oct 11, 2024
16b177d
goofing around
cklutz Oct 11, 2024
b70cd01
goofing around
cklutz Oct 11, 2024
d20382a
goofing around
cklutz Oct 11, 2024
0c5b963
goofing around
cklutz Oct 11, 2024
44bd527
goofing around
cklutz Oct 11, 2024
2c619d9
goofing around
cklutz Oct 11, 2024
05b9e81
goofing around
cklutz Oct 11, 2024
2f9e9b6
goofing around
cklutz Oct 11, 2024
518d3c3
goofing around
cklutz Oct 11, 2024
e2adffc
goofing around
cklutz Oct 11, 2024
c706f3a
goofing around
cklutz Oct 11, 2024
2d54ad9
goofing around
cklutz Oct 11, 2024
a323502
goofing around
cklutz Oct 11, 2024
694ffcb
goofing around
cklutz Oct 11, 2024
7a8c1e6
goofing around
cklutz Oct 11, 2024
e34d5ae
goofing around
cklutz Oct 11, 2024
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
128 changes: 128 additions & 0 deletions .github/workflows/dotnet-reusable-workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
name: DotNet Reusable Workflow

on:
workflow_call:
inputs:
runs-on:
description: 'The OS to run the build/tests on'
required: true
type: string
dotnet-version:
description: 'The .NET version to use'
required: true
type: string
configuration:
description: 'The build configuration to build/test'
required: true
type: string
tfm:
description: 'The target framework to build/test for'
required: true
type: string
code-coverage:
description: 'Enable code coverage during unit tests (will only run for `code-coverage-configuration`)'
required: false
type: boolean
default: false
code-coverage-configuration:
description: 'The build configuration to run code coverage for (will only run if `code-coverage` is `true`)'
required: false
type: string
default: Release
code-coverage-badge:
description: 'Enable generating a batch for code coverage'
required: false
type: boolean
default: false

jobs:
build:
runs-on: ${{ inputs.runs-on }}

env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
LC_PIVOT: ${{ inputs.tfm }}-${{ inputs.configuration }}

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # avoid shallow clone so that nbgv can do its work.

- name: Setup .NET (64 bit)
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ inputs.dotnet-version }}

- name: Configure
id: configure
run: |
shopt -s nocasematch
if [[ "${{ inputs.runs-on }}" == *"windows"* ]]; then
echo "LC_COVERAGE_EXCLUDE_CLASS_FILTER=-*.Linux.*" >> "$GITHUB_OUTPUT"
elif [[ "${{ inputs.runs-on }}" == *"ubuntu"* ]]; then
echo "LC_COVERAGE_EXCLUDE_CLASS_FILTER=-*.Windows.*" >> "$GITHUB_OUTPUT"
fi
if [[ "${{ inputs.code-coverage }}" == "true" ]]; then
echo "LC_COVERAGE_TEST_OPTIONS=--collect \"Code Coverage;Format=Cobertura\"" >> "$GITHUB_OUTPUT"
fi
shell: bash

- name: Build
run: >
dotnet build
--framework ${{ inputs.tfm }}
--configuration ${{ inputs.configuration }}

- name: Test
run: >
dotnet test
--no-build
--framework ${{ inputs.tfm }}
--configuration ${{ inputs.configuration }}
${{ steps.configure.outputs.LC_COVERAGE_TEST_OPTIONS }}
--verbosity normal
--logger trx
--results-directory "TestResults-${{ env.LC_PIVOT }}"

- name: Upload TestResults
uses: actions/upload-artifact@v4
with:
name: test-results-${{ env.LC_PIVOT }}
path: TestResults-${{ env.LC_PIVOT }}
if: ${{ always() }}

- name: Generage coverage report
uses: danielpalme/[email protected]
with:
reports: '${{ github.workspace }}/TestResults-${{ env.LC_PIVOT }}/**/*.cobertura.xml'
targetdir: '${{ github.workspace }}/CoverageReport-${{ env.LC_PIVOT }}'
reporttypes: 'Html;Html_Dark;Cobertura;MarkdownSummaryGithub;Badges;JsonSummary'
assemblyfilters: '-*.Tests;-LCTestTarget*'
classfilters: '${{ steps.configure.outputs.LC_COVERAGE_EXCLUDE_CLASS_FILTER }}'
title: 'Results for ${{ inputs.tfm }}, ${{ inputs.configuration }}'
tag: '${{ github.run_number }}_${{ github.run_id }}'
if: ${{ inputs.code-coverage && inputs.configuration == inputs.code-coverage-configuration }}

- name: Add coverage report to summary
run: cat $GITHUB_WORKSPACE/CoverageReport-${{ env.LC_PIVOT }}/SummaryGithub.md >> $GITHUB_STEP_SUMMARY
shell: bash
if: ${{ inputs.code-coverage && inputs.configuration == inputs.code-coverage-configuration }}

- name: Update CodeCoverage badge
run: |
chmod +rx .github/workflows/update_gist.sh
.github/workflows/update_gist.sh 9bd61dea93406219c4985641039c4e2f \
code-coverage-windows-${{ env.LC_PIVOT }}.svg \
$GITHUB_WORKSPACE/CoverageReport-${{ env.LC_PIVOT }}/badge_combined.svg
shell: bash
env:
GH_TOKEN: ${{ secrets.BADGE_GIST_TOKEN }}
if: ${{ inputs.code-coverage && inputs.code-coverage-badge && inputs.configuration == inputs.code-coverage-configuration }}

- name: Upload CoverageReport
uses: actions/upload-artifact@v4
with:
name: coverage-report-${{ env.LC_PIVOT }}
path: CoverageReport-${{ env.LC_PIVOT }}
if: ${{ always() && inputs.code-coverage && inputs.configuration == inputs.code-coverage-configuration }}
67 changes: 17 additions & 50 deletions .github/workflows/dotnet-ubuntu.yml
Original file line number Diff line number Diff line change
@@ -1,57 +1,24 @@
name: Ubuntu

on:
# Allow to use "gh.exe workflow run Ubuntu --ref <branchname>" to trigger this workflow for arbitrary branches.
workflow_dispatch:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
build:
strategy:
matrix:
configuration: [Debug, Release]
dotnet-version: ['8.0.x']
tfm: ['net8.0']

runs-on: ubuntu-latest

env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: true

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # avoid shallow clone so that nbgv can do its work.

- name: Setup .NET (64 bit)
uses: actions/setup-dotnet@v3
build:
strategy:
matrix:
runs-on: ['ubuntu-latest']
configuration: [Debug, Release]
dotnet-version: ['8.0.x']
tfm: ['net8.0']
uses: ./.github/workflows/dotnet-reusable-workflow.yml
with:
runs-on: ${{ matrix.runs-on }}
dotnet-version: ${{ matrix.dotnet-version }}

- name: Build
run: >
dotnet build
--framework ${{ matrix.tfm }}
--configuration ${{ matrix.configuration }}

- name: Test
run: >
dotnet test
--no-build
--framework ${{ matrix.tfm }}
--verbosity normal
--configuration ${{ matrix.configuration }}
--logger trx
--results-directory "TestResults-${{ matrix.tfm }}-${{ matrix.configuration }}"

- name: Upload dotnet test results
uses: actions/upload-artifact@v4
with:
name: test-results-${{ matrix.tfm }}-${{ matrix.configuration }}
path: TestResults-${{ matrix.tfm }}-${{ matrix.configuration }}
# Use always() to always run this step to publish test results when there are test failures
if: ${{ always() }}
configuration: ${{ matrix.configuration }}
tfm: ${{ matrix.tfm }}
code-coverage: true
72 changes: 17 additions & 55 deletions .github/workflows/dotnet-windows.yml
Original file line number Diff line number Diff line change
@@ -1,62 +1,24 @@
name: Windows

on:
# Allow to use "gh.exe workflow run Windows --ref <branchname>" to trigger this workflow for arbitrary branches.
workflow_dispatch:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
build:
strategy:
matrix:
configuration: [Debug, Release]
dotnet-version: ['8.0.x']
tfm: ['net8.0', 'net481']

runs-on: windows-latest

env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: true

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # avoid shallow clone so that nbgv can do its work.

- name: Setup .NET (64 bit)
uses: actions/setup-dotnet@v3
build:
strategy:
matrix:
runs-on: ['windows-latest']
configuration: [Debug, Release]
dotnet-version: ['8.0.x']
tfm: ['net8.0', 'net481']
uses: ./.github/workflows/dotnet-reusable-workflow.yml
with:
runs-on: ${{ matrix.runs-on }}
dotnet-version: ${{ matrix.dotnet-version }}

#- name: List Runtimes 64 bit
# run: cmd /c "C:\Program Files\dotnet\dotnet.exe" --list-runtimes
#- name: List Runtimes 32 bit
# run: cmd /c "C:\Program Files (x86)\dotnet\dotnet.exe" --list-runtimes

- name: Build
run: >
dotnet build
--framework ${{ matrix.tfm }}
--configuration ${{ matrix.configuration }}

- name: Test
run: >
dotnet test
--no-build
--framework ${{ matrix.tfm }}
--verbosity normal
--configuration ${{ matrix.configuration }}
--logger trx
--results-directory "TestResults-${{ matrix.tfm }}-${{ matrix.configuration }}"

- name: Upload dotnet test results
uses: actions/upload-artifact@v4
with:
name: test-results-${{ matrix.tfm }}-${{ matrix.configuration }}
path: TestResults-${{ matrix.tfm }}-${{ matrix.configuration }}
# Use always() to always run this step to publish test results when there are test failures
if: ${{ always() }}
configuration: ${{ matrix.configuration }}
tfm: ${{ matrix.tfm }}
code-coverage: true
50 changes: 50 additions & 0 deletions .github/workflows/update_gist.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/bash

SCRIPT_NAME=$(basename $0)

if [[ $# -lt 2 ]]; then
echo "Usage: $SCRIPT_NAME GIST_ID FILE LOCAL_FILE" 1>&2
exit 1
fi

GIST_ID=$1
FILE=$2
LOCAL_FILE=$3
MAX_RETRIES=10 # Maximum number of retries
RETRY_DELAY=1 # Delay between retries in seconds


for ((i=1; i<=MAX_RETRIES; i++)); do
echo "$SCRIPT_NAME: Attempt $i of $MAX_RETRIES to update gist..."

# Try to update the gist
echo $SCRIPT_NAME: gh gist edit "$GIST_ID" -f "$FILE" "$LOCAL_FILE"
OUTPUT=$(gh gist edit "$GIST_ID" -f "$FILE" "$LOCAL_FILE" 2>&1)
EXIT_CODE=$?

# Check if the update succeeded
if [[ $EXIT_CODE -eq 0 ]]; then
echo $OUTPUT
exit 0
fi

# Check if it's a 409 Conflict
if echo "$OUTPUT" | grep -q "HTTP 409"; then
# Increase delay if tried to often already
if [[ $i -ge 7 ]]; then
RETRY_DELAY=$((RETRY_DELAY * 5))
elif [[ $i -ge 5 ]]; then
RETRY_DELAY=$((RETRY_DELAY * 2))
fi
echo "$SCRIPT_NAME: Received HTTP 409 conflict. Retrying in $RETRY_DELAY seconds..."
sleep $RETRY_DELAY
else
# Exit if it's any other error
echo $OUTPUT
exit $EXIT_CODE
fi
done

echo "$SCRIPT_NAME: Failed to update gist after $MAX_RETRIES attempts."
echo $OUTPUT
exit 1
8 changes: 4 additions & 4 deletions src/LockCheck/ProcessInfo.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
Expand Down Expand Up @@ -124,7 +124,7 @@ public string ToString(string format)
return ToString();
}

public static void Format(StringBuilder sb, IEnumerable<ProcessInfo> lockers, IEnumerable<string> fileNames, int? maxProcesses = null)
public static void Format(StringBuilder sb, IEnumerable<ProcessInfo> lockers, IEnumerable<string> fileNames, int? maxProcesses = null, string ownerOverwrite = null)
{
if (lockers == null || !lockers.Any())
return;
Expand All @@ -135,7 +135,7 @@ public static void Format(StringBuilder sb, IEnumerable<ProcessInfo> lockers, IE
sb.AppendFormat("File {0} locked by: ", string.Join(", ", fileNames));
foreach (ProcessInfo locker in lockers.Take(max))
{
sb.AppendLine($"[{locker.ApplicationName}, pid={locker.ProcessId}, owner={locker.Owner}, started={locker.StartTime:yyyy-MM-dd HH:mm:ss.fff}]");
sb.AppendLine($"[{locker.ApplicationName}, pid={locker.ProcessId}, owner={ownerOverwrite ?? locker.Owner}, started={locker.StartTime:yyyy-MM-dd HH:mm:ss.fff}]");
}

if (count > max)
Expand All @@ -144,4 +144,4 @@ public static void Format(StringBuilder sb, IEnumerable<ProcessInfo> lockers, IE
}
}
}
}
}
13 changes: 12 additions & 1 deletion test/LockCheck.Tests/ExceptionUtilsTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;

Expand Down Expand Up @@ -42,7 +43,17 @@ public void RethrownExceptionContainsInformation(LockManagerFeatures features)
var processInfos = LockManager.GetLockingProcessInfos([ fileName], features).ToList();
Assert.AreEqual(1, processInfos.Count); // Sanity, has been tested in LockManagerTests
var expectedMessageContents = new StringBuilder();
ProcessInfo.Format(expectedMessageContents, processInfos, [fileName]);

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// Getting the owner is not really stable on Windows, it seems.
ProcessInfo.Format(expectedMessageContents, processInfos, [fileName],
ownerOverwrite: $@"{Environment.UserDomainName}\{Environment.UserName}");
}
else
{
ProcessInfo.Format(expectedMessageContents, processInfos, [fileName]);
}

try
{
Expand Down