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 .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Default owner for everything
* @erlendellefsen

# Security-sensitive files require extra review
.github/workflows/** @erlendellefsen
44 changes: 44 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
version: 2

updates:
# NuGet packages
- package-ecosystem: nuget
directory: /
schedule:
interval: weekly
day: monday
open-pull-requests-limit: 10
labels:
- dependencies
- nuget
commit-message:
prefix: "deps(nuget)"
groups:
# Group minor/patch updates to reduce PR noise
microsoft:
patterns:
- "Microsoft.*"
update-types:
- minor
- patch
testing:
patterns:
- "xunit*"
- "Moq*"
- "coverlet*"
update-types:
- minor
- patch

# GitHub Actions
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
day: monday
open-pull-requests-limit: 5
labels:
- dependencies
- github-actions
commit-message:
prefix: "deps(actions)"
26 changes: 26 additions & 0 deletions .github/release-please-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/refs/heads/main/schemas/config.json",
"packages": {
".": {
"release-type": "simple",
"package-name": "Intility.JsonApiToolkit",
"changelog-sections": [
{ "type": "feat", "section": "Features", "hidden": false },
{ "type": "fix", "section": "Bug Fixes", "hidden": false },
{ "type": "perf", "section": "Performance", "hidden": false },
{ "type": "refactor", "section": "Refactoring", "hidden": false },
{ "type": "docs", "section": "Documentation", "hidden": false },
{ "type": "test", "section": "Tests", "hidden": true },
{ "type": "chore", "section": "Maintenance", "hidden": true },
{ "type": "deps", "section": "Dependencies", "hidden": false }
],
"extra-files": [
{
"type": "xml",
"path": "JsonApiToolkit/JsonApiToolkit.csproj",
"xpath": "//Project/PropertyGroup/Version"
}
]
}
}
}
3 changes: 3 additions & 0 deletions .github/release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
".": "1.2.5"
}
22 changes: 0 additions & 22 deletions .github/release.yml

This file was deleted.

97 changes: 58 additions & 39 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,74 @@ name: CI/CD Pipeline

on:
push:
branches: [ main ]
branches: [main]
paths-ignore:
- "docs/**"
- "**.md"
- ".github/ISSUE_TEMPLATE/**"
- ".claude/**"
pull_request:
branches: [ main ]
branches: [main]
paths-ignore:
- "docs/**"
- "**.md"
- ".github/ISSUE_TEMPLATE/**"
- ".claude/**"
release:
types: [ published ]
types: [published]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build-and-test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.x.x

- name: Restore dependencies
run: dotnet restore

- name: Build
run: dotnet build --no-restore --configuration Release

- name: Test
run: dotnet test --no-build --configuration Release --verbosity normal
- uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.x

- name: Restore dependencies
run: dotnet restore

- name: Check formatting
run: |
dotnet tool restore
dotnet csharpier . --check
- name: Build
run: dotnet build --no-restore --configuration Release

- name: Test
run: dotnet test --no-build --configuration Release --verbosity normal

publish:
needs: build-and-test
if: github.event_name == 'release'
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.x.x
source-url: https://nuget.pkg.github.com/Intility/index.json
env:
NUGET_AUTH_TOKEN: ${{ secrets.NUGET_AUTH_TOKEN }}
- name: Build and Pack
run: |
VERSION="${{ github.event.release.tag_name }}"
# Remove v prefix if present
[[ "$VERSION" =~ ^v ]] && VERSION="${VERSION:1}"
dotnet pack JsonApiToolkit/JsonApiToolkit.csproj -p:PackageVersion=$VERSION -c Release
- name: Publish to GitHub Packages
run: dotnet nuget push "JsonApiToolkit/bin/Release/*.nupkg" --api-key ${{ secrets.NUGET_AUTH_TOKEN }}
- uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.x
source-url: https://nuget.pkg.github.com/Intility/index.json
env:
NUGET_AUTH_TOKEN: ${{ secrets.NUGET_AUTH_TOKEN }}

- name: Build and Pack
run: |
VERSION="${{ github.event.release.tag_name }}"
# Remove v prefix if present
[[ "$VERSION" =~ ^v ]] && VERSION="${VERSION:1}"
dotnet pack JsonApiToolkit/JsonApiToolkit.csproj -p:PackageVersion=$VERSION -c Release
- name: Publish to GitHub Packages
run: dotnet nuget push "JsonApiToolkit/bin/Release/*.nupkg" --api-key ${{ secrets.NUGET_AUTH_TOKEN }}
52 changes: 52 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: CodeQL

on:
push:
branches: [main]
paths:
- "**.cs"
- "**.csproj"
pull_request:
branches: [main]
paths:
- "**.cs"
- "**.csproj"
schedule:
- cron: "0 6 * * 1" # Monday 6am UTC

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
security-events: write
packages: read
actions: read
contents: read

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.x

- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: csharp
queries: security-and-quality

- name: Build
run: dotnet build --configuration Release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:csharp"
31 changes: 31 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Release Please

permissions:
contents: write
pull-requests: write

on:
push:
branches:
- main

jobs:
release-please:
if: github.event_name == 'push'
name: 🚀 Release Please
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf
id: app-token
with:
app-id: ${{ vars.RELEASE_BOT_APP_ID }}
private-key: ${{ secrets.RELEASE_BOT_PRIVATE_KEY }}

- uses: googleapis/release-please-action@16a9c90856f42705d54a6fda1823352bdc62cf38
with:
token: ${{ steps.app-token.outputs.token }}
config-file: .github/release-please-config.json
manifest-file: .github/release-please-manifest.json
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

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

manifest-file points to .github/release-please-manifest.json, but this PR adds the manifest as .github/.release-please-manifest.json (leading dot). Release-please will fail to start because it can’t find the manifest. Rename the manifest file or update manifest-file to the correct path so they match.

Suggested change
manifest-file: .github/release-please-manifest.json
manifest-file: .github/.release-please-manifest.json

Copilot uses AI. Check for mistakes.
18 changes: 9 additions & 9 deletions JsonApiToolkit.Tests/Extensions/FilteredIncludeBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ public void ApplyFilteredIncludes_WithSimpleIncludeFilter_BuildsCorrectExpressio
Field = "status",
Operator = FilterOperator.Eq,
Value = "approved",
}
}
}
},
},
},
},
};

Expand Down Expand Up @@ -114,9 +114,9 @@ public void ApplyFilteredIncludes_WithMultipleFiltersOnSameRelationship_Combines
Field = "priority",
Operator = FilterOperator.Gt,
Value = "5",
}
}
}
},
},
},
},
};

Expand Down Expand Up @@ -162,9 +162,9 @@ public void ApplyFilteredIncludes_WithMixedFilteredAndUnfilteredIncludes_Handles
Field = "status",
Operator = FilterOperator.Eq,
Value = "approved",
}
}
}
},
},
},
},
// tags and author have no filters
};
Expand Down
26 changes: 16 additions & 10 deletions JsonApiToolkit.Tests/Parsing/JsonApiQueryParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -303,11 +303,14 @@ public void Parse_WithOrChainDotNotation_CreatesPrimaryFilters()
Assert.Equal(2, orGroup.Filters.Count);

// Both should be primary filters (dot notation)
Assert.All(orGroup.Filters, f =>
{
Assert.Equal("vulnerability.severity", f.Field);
Assert.False(f.IsIncludeFilter);
});
Assert.All(
orGroup.Filters,
f =>
{
Assert.Equal("vulnerability.severity", f.Field);
Assert.False(f.IsIncludeFilter);
}
);
}

[Fact]
Expand All @@ -333,11 +336,14 @@ public void Parse_WithOrChainBracketSyntax_CreatesIncludeFilters()
Assert.Equal(2, orGroup.Filters.Count);

// Both should be include filters (bracket syntax)
Assert.All(orGroup.Filters, f =>
{
Assert.Equal("vulnerability.severity", f.Field);
Assert.True(f.IsIncludeFilter);
});
Assert.All(
orGroup.Filters,
f =>
{
Assert.Equal("vulnerability.severity", f.Field);
Assert.True(f.IsIncludeFilter);
}
);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,12 @@ public static class FilterExpressionBuilder

foreach (FilterGroup nestedGroup in group.Groups)
{
Expression? nestedExpr = BuildFilterExpression(nestedGroup, parameter, entityType, logger);
Expression? nestedExpr = BuildFilterExpression(
nestedGroup,
parameter,
entityType,
logger
);
if (nestedExpr != null)
expressions.Add(nestedExpr);
}
Expand Down
Loading
Loading