Conversation
There was a problem hiding this comment.
Pull request overview
This pull request adds perpetual licensing support to AutoMapper, allowing licenses to remain valid for builds created before the license expiration date, even after the license has expired. The implementation introduces a build date timestamp that is embedded in the assembly at compile time and checked against the license expiration date during validation.
Changes:
- Added build date tracking via assembly metadata embedded during compilation
- Implemented perpetual license claim parsing and validation logic
- Added comprehensive test coverage for perpetual licensing scenarios
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/AutoMapper/Licensing/BuildInfo.cs | New class to extract build date from assembly metadata attributes |
| src/AutoMapper/AutoMapper.csproj | MSBuild target to embed current UTC timestamp as assembly metadata during compilation |
| src/AutoMapper/Licensing/License.cs | Added IsPerpetual property to parse "perpetual" claim from license tokens |
| src/AutoMapper/Licensing/LicenseValidator.cs | Enhanced validation logic to allow expired perpetual licenses when build date precedes expiration |
| src/UnitTests/Licensing/LicenseValidatorTests.cs | Three new test cases covering perpetual license validation scenarios |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <Target Name="EmbedBuildDate" BeforeTargets="CoreCompile"> | ||
| <PropertyGroup> | ||
| <BuildDateUtc>$([System.DateTime]::UtcNow.ToString("O"))</BuildDateUtc> | ||
| </PropertyGroup> | ||
| <WriteLinesToFile File="$(IntermediateOutputPath)BuildDateGenerated.cs" Lines="[assembly: System.Reflection.AssemblyMetadata("BuildDateUtc", "$(BuildDateUtc)")]" Overwrite="true" /> | ||
| <ItemGroup> | ||
| <Compile Include="$(IntermediateOutputPath)BuildDateGenerated.cs" /> | ||
| </ItemGroup> | ||
| </Target> |
There was a problem hiding this comment.
The EmbedBuildDate target uses DateTime.UtcNow which makes every build produce a different assembly, conflicting with the Deterministic build setting on line 26. This will break deterministic builds and may cause issues with build caching, reproducible builds, and package signing.
Consider using a source control-based approach (like git commit timestamp) or an environment variable that can be set to a fixed value in CI/CD pipelines while allowing dynamic values for local development builds. For example, you could check for an environment variable first: BuildDateUtc>$([System.Environment]::GetEnvironmentVariable('BUILD_DATE_UTC', 'EnvironmentVariableTarget.Process'))</BuildDateUtc> and only fall back to UtcNow if not set, or use SOURCE_DATE_EPOCH for reproducible builds.
| [Fact] | ||
| public void Should_handle_missing_perpetual_claim() | ||
| { | ||
| var factory = new LoggerFactory(); | ||
| var provider = new FakeLoggerProvider(); | ||
| factory.AddProvider(provider); | ||
|
|
||
| var licenseValidator = new LicenseValidator(factory); | ||
| var license = new License( | ||
| new Claim("account_id", Guid.NewGuid().ToString()), | ||
| new Claim("customer_id", Guid.NewGuid().ToString()), | ||
| new Claim("sub_id", Guid.NewGuid().ToString()), | ||
| new Claim("iat", DateTimeOffset.UtcNow.AddDays(-1).ToUnixTimeSeconds().ToString()), | ||
| new Claim("exp", DateTimeOffset.UtcNow.AddDays(1).ToUnixTimeSeconds().ToString()), | ||
| new Claim("edition", nameof(Edition.Community)), | ||
| new Claim("type", nameof(AutoMapper.Licensing.ProductType.Bundle))); | ||
|
|
||
| license.IsConfigured.ShouldBeTrue(); | ||
| license.IsPerpetual.ShouldBeFalse(); | ||
|
|
||
| licenseValidator.Validate(license); | ||
|
|
||
| var logMessages = provider.Collector.GetSnapshot(); | ||
| logMessages.ShouldNotContain(log => log.Level == LogLevel.Error | ||
| || log.Level == LogLevel.Warning | ||
| || log.Level == LogLevel.Critical); | ||
| } |
There was a problem hiding this comment.
The tests don't cover the edge case where a perpetual license is used but the build date is unavailable (null). According to the validation logic on line 37 of LicenseValidator.cs, if _buildDate is null, the perpetual license feature won't activate and the expired license will be rejected.
Add a test case that validates an expired perpetual license when no build date is provided (call new LicenseValidator(factory) without passing a buildDate, and ensure BuildInfo.BuildDate returns null in the test context). This should verify that the system gracefully handles this scenario and logs an appropriate error.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
No description provided.