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.
Updated [AutoMapper](https://github.com/LuckyPennySoftware/AutoMapper) from 14.0.0 to 16.1.0. <details> <summary>Release notes</summary> _Sourced from [AutoMapper's releases](https://github.com/LuckyPennySoftware/AutoMapper/releases)._ ## 16.1.0 ## What's Changed * Add Debug and Release build configurations to slnx by @Copilot in LuckyPennySoftware/AutoMapper#4590 * Migrating to slnx by @jbogard in LuckyPennySoftware/AutoMapper#4589 * Allow disabling of polymorphic LINQ mapping by @jbogard in LuckyPennySoftware/AutoMapper#4596 * Fix duplicate BOM in ServiceCollectionExtensions.cs by @Copilot in LuckyPennySoftware/AutoMapper#4600 * Fix review feedback: double semicolon, DI condition integration test, docs example by @Copilot in LuckyPennySoftware/AutoMapper#4601 * Adding DI-enabled conditions and pre-conditions; updated docs accordi… by @jbogard in LuckyPennySoftware/AutoMapper#4599 * Adding support for DI-enabled destination factories. by @jbogard in LuckyPennySoftware/AutoMapper#4603 * Correctly converting nullables for MapAtRuntime; fixes #4597 by @jbogard in LuckyPennySoftware/AutoMapper#4604 * Correctly handling consecutive uppercase characters; fixes #4593 by @jbogard in LuckyPennySoftware/AutoMapper#4605 * Wrapping the exception to provide better feedback to the user; fixes … by @jbogard in LuckyPennySoftware/AutoMapper#4606 * Fixing bug around order of open generic registration by @jbogard in LuckyPennySoftware/AutoMapper#4607 * Adding perpetual licensing by @jbogard in LuckyPennySoftware/AutoMapper#4608 ## New Contributors * @Copilot made their first contribution in LuckyPennySoftware/AutoMapper#4590 **Full Changelog**: LuckyPennySoftware/AutoMapper@v16.0.0...v16.1.0 ## 16.0.0 ## What's Changed * Fix release pipelines by @jbogard in LuckyPennySoftware/AutoMapper#4583 * Adding support for .NET 10 by @jbogard in LuckyPennySoftware/AutoMapper#4586 **Full Changelog**: LuckyPennySoftware/AutoMapper@v15.1.0...v16.0.0 ## 16.0.0-beta-1 ## What's Changed * Fix release pipelines by @jbogard in LuckyPennySoftware/AutoMapper#4583 * Adding support for .NET 10 by @jbogard in LuckyPennySoftware/AutoMapper#4586 **Full Changelog**: LuckyPennySoftware/AutoMapper@v15.1.0...v16.0.0-beta-1 This release is a beta release that introduces .NET 10 support and package signing. Signed packages means going forward packages can be validated against trusted authorities that the package has been published by Lucky Penny Software and not tampered with. ## 15.1.0 ## What's Changed * remove Microsoft.SourceLink.GitHub by @SimonCropp in LuckyPennySoftware/AutoMapper#4555 * Direct .NET 4.x support by @jbogard in LuckyPennySoftware/AutoMapper#4569 * Bumping the JsonWebTokens because of GHSA-8g4q-xg66-9fp4; fixes #4575 by @jbogard in LuckyPennySoftware/AutoMapper#4576 * Provide better exceptions for errors when building the mapping plan by @jbogard in LuckyPennySoftware/AutoMapper#4577 * Adding docs for license configuration by @jbogard in LuckyPennySoftware/AutoMapper#4581 * Updating refs to fix missing method issue by @jbogard in LuckyPennySoftware/AutoMapper#4582 ## New Contributors * @SimonCropp made their first contribution in LuckyPennySoftware/AutoMapper#4555 **Full Changelog**: LuckyPennySoftware/AutoMapper@v15.0.1...v15.1.0 ## 15.0.1 ## What's Changed * Removing public signing; fixes #4545 by @jbogard in LuckyPennySoftware/AutoMapper#4552 * Adding back missing overloads and reverting registering behavior by @jbogard in LuckyPennySoftware/AutoMapper#4554 **Full Changelog**: LuckyPennySoftware/AutoMapper@v15.0.0...v15.0.1 This release supersedes the 15.0.0 release, reverting behavior and overloads so that the `AddAutoMapper` overloads separate the "scanning for maps" from the "scanning for dependencies". Unfortunately it's not really possible to combine these two together. This also fixes a critical bug in #4545 that does not work with .NET 4.x applications (as intended). Because of this, the 15.0.0 will be delisted because of the breaking changes there. ## 15.0.0 **Full Changelog**: LuckyPennySoftware/AutoMapper@v14.0.0...v15.0.0 * Added support for .NET Standard 2.0 * Requiring license key * Moving from MIT license to dual commercial/OSS license To set your license key: ```csharp services.AddAutoMapper(cfg => { cfg.LicenseKey = "<License key here>"; }); ``` This also introduced a breaking change with `MapperConfiguration` requiring an `ILoggerFactory` for logging purposes: ```csharp public MapperConfiguration(MapperConfigurationExpression configurationExpression, ILoggerFactory loggerFactory) ``` Registering AutoMapper with `services.AddAutoMapper` will automatically supply this parameter. Otherwise you'll need to supply the logger factory. You can obtain your license key at [AutoMapper.io](https://automapper.io) Commits viewable in [compare view](LuckyPennySoftware/AutoMapper@v14.0.0...v16.1.0). </details> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
No description provided.