Skip to content

🚀 AWS SDK v4 Migration - v2.0.0-preview1 Release #46

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

Merged
merged 9 commits into from
Jul 16, 2025

Conversation

Blind-Striker
Copy link
Contributor

This PR completes the migration from AWS SDK for .NET v3 to v4, enabling the first preview release of LocalStack.NET v2.0.0 series.

Breaking Changes

  • Framework Support: Deprecated .NET Framework 4.6.2, added .NET Framework 4.7.2 requirement
  • AWS SDK Compatibility: Complete migration to AWS SDK v4.x series (70+ packages updated)

Key Changes

  • Core Migration: Updated AWSSDK.Core to 4.0.0.15 and AWSSDK.Extensions.NETCore.Setup to 4.0.2
  • Extensions Fix: Migrated AwsClientFactoryWrapper from non-generic ClientFactory to ClientFactory<T> pattern
  • Test Resolution: Fixed AWS SDK v4 behavioral changes in functional tests
    • Added null-conditional operators for SNS Topics and SQS Messages collections
    • Fixed DynamoDB entity GSI attribute decoration requirements
    • Corrected test constant naming issues

Testing Validation

  • 1,099 total tests passing across all target frameworks
  • All packages build successfully for preview release
  • Multi-framework support: .NET 8, 9, Standard 2.0, Framework 4.7.2
  • LocalStack compatibility: Tested against v3.7.1 and v4.3.0

Important Notes

  • No API Changes: LocalStack.NET public APIs remain unchanged - only internal AWS SDK v4 compatibility
  • Preview Release: Early adopter release for testing and feedback
  • Migration Required: Users need AWS SDK v4 packages and .NET Framework 4.7.2+

Related

Commits

  • feat!: migrate to AWS SDK for .NET v4 with breaking changes
  • feat(extensions)!: migrate AwsClientFactoryWrapper to AWS SDK v4
  • fix: resolve test failures and update package versions for v2.0.0-preview1
  • feat: implement AWS SDK v4 migration with .NET Framework 4.7.2 support

Ready for preview package publication! 🎉

BREAKING CHANGE: Update from AWS SDK v3.7.x to v4.x series with new minimum .NET Framework requirement

### Major Changes:
- **AWS SDK Upgrade**: All 70+ AWS SDK packages updated from v3.7.x to v4.x
- **Framework Update**: .NET Framework support updated from 4.6.2 to 4.7.2 (AWS SDK v4 requirement)
- **Static Interface Compliance**: Implemented AWS SDK v4 static interface methods with conditional compilation

### Core Library Updates:
- Update LocalStack.Client target frameworks: netstandard2.0;net472;net8.0;net9.0
- Add conditional compilation support for NET472 framework constants
- Update GlobalUsings.cs IsExternalInit support for NET472

### Extensions Library:
- Implement backward-compatible Microsoft.Extensions package strategy
- Add conditional version overrides for legacy (.NET Standard 2.0) vs modern (.NET 8+) frameworks
- Maintain netstandard2.0;net8.0;net9.0 targets (no .NET Framework for DI scenarios)

### Test Infrastructure:
- Update all test projects to net472;net8.0;net9.0 framework support
- Implement AWS SDK v4 static interface methods in mock service clients
- Add DetermineServiceOperationEndpoint implementation in MockClientConfig
- Apply focused pragma suppressions for AWS SDK v4 compatibility

### Build System:
- Update build scripts for net472 framework logic
- Maintain centralized package management with AWS SDK v4 versions
- Add TestPlatform.ObjectModel conditional dependency for net472

Resolves Phase 1 of AWS SDK v4 migration roadmap.
All core libraries and test infrastructure now fully compatible with AWS SDK v4.
…view1

- Add parameterless constructor to MockClientConfig for reflection compatibility
- Fix MockClientConfigWithForcePathStyle default ForcePathStyle value
- Update package versions to 2.0.0-preview1 for preview release

Test Results:
- ✅ LocalStack.Client.Tests: 91/91 tests passing
- ✅ Package creation: Both main and extensions packages built successfully
- ⚠️ Extensions test failure: AWS SDK v4 ClientFactory reflection issue (known issue, requires separate fix)

Phase 2 package validation mostly complete - core functionality verified.
BREAKING CHANGE: Extensions package now requires AWS SDK v4

- Replace non-generic ClientFactory with ClientFactory<T>
- Update constructor to use AWSOptions-only signature
- Fix method resolution for CreateServiceClient(IServiceProvider)
- Add comprehensive error handling tests
- Remove AWS SDK v3 compatibility layer

Resolves Extensions test failures blocking v2.0.0-preview1 release.
All 38 Extensions tests now passing.
BREAKING CHANGE: Complete migration from AWS SDK for .NET v3 to v4

- Collections in AWS models now default to null instead of empty collections
- DynamoDB entity validation requires proper attribute decoration for GSI operations
- Applications must implement null-conditional operators for collection access

Key Changes:
- Fixed SNS Topics collection null-safety in functional tests
- Fixed SQS Messages collection null-safety in functional tests
- Added DynamoDB entity GSI attribute decoration for MovieEntity
- Corrected MovieTableMovie index name typo in test constants
- All 1,099 tests passing across .NET 8, 9, Standard 2.0, Framework 4.7.2
@Blind-Striker Blind-Striker requested a review from Copilot July 13, 2025 17:27
@Blind-Striker Blind-Striker self-assigned this Jul 13, 2025
@Blind-Striker Blind-Striker added the enhancement New feature or request label Jul 13, 2025
Copilot

This comment was marked as outdated.

* feat: modernize CI/CD pipeline infrastructure

✨ Phase 1: Infrastructure Modernization Complete

## 🚀 New Features
- **Modern CI/CD Pipeline**: Consolidated 3 separate OS workflows into unified matrix-based ci.yml
- **Automated GitHub Packages**: Daily development builds for immediate testing feedback
- **Enhanced Security**: CodeQL analysis + Dependabot automation
- **GitHub Test Reporter**: Native test result visualization (replaces Testspace)

## 🔄 Workflow Changes
- ✅ **ci.yml**: Cross-platform matrix testing (Windows/Linux/macOS) with modern actions
- ✅ **publish-dev-github.yml**: Automated GitHub Packages publishing for development
- ✅ **publish-nuget.yml**: Enhanced manual workflow supporting both GitHub Packages & NuGet.org
- ✅ **security.yml**: CodeQL security scanning + dependency review
- ✅ **dependabot.yml**: Automated dependency management with smart grouping

## 🏗️ Infrastructure Updates
- **GitHub Actions**: Updated to v4 (checkout, setup-dotnet, cache, upload-artifact)
- **Runners**: Migrated from ubuntu-20.04 to ubuntu-latest
- **Test Reporting**: Native GitHub integration via dorny/test-reporter@v1
- **Package Caching**: Optimized NuGet package caching for faster builds
- **Build System**: Added GitHub Packages support to Cake Frosting build

## 🗑️ Removed Deprecated Components
- ❌ **Old Workflows**: build-ubuntu.yml, build-windows.yml, build-macos.yml
- ❌ **Testspace**: External test reporting service dependency
- ❌ **Old Actions**: checkout@v2, setup-dotnet@v1, setup-nuget@v1.0.5

## 📦 Release Strategy
- **Development**: Auto-publish to GitHub Packages on every master/v2-preview1 commit
- **Preview/Stable**: Manual NuGet.org publishing with enhanced dropdown workflow
- **Version Format**: 2.0.0-preview1.20240715.a1b2c3d for development builds

Ready for Phase 2: Enhanced automation & community features! 🎯

* docs: update README with modernized CI/CD information

✨ Enhanced Documentation

## 📖 Updated Content
- **CI/CD Badges**: Modern GitHub Actions workflow status badges
- **Package Installation**: Dual-source strategy (NuGet.org + GitHub Packages)
- **Development Builds**: Instructions for GitHub Packages authentication
- **CI Status**: Matrix testing status across Windows/Linux/macOS

## 🔄 Badge Updates
- ✅ **CI/CD Pipeline**: Cross-platform matrix testing status
- ✅ **Security Analysis**: CodeQL scanning and dependency review
- ✅ **Automated Publishing**: GitHub Packages development builds
- ❌ **Removed**: Deprecated Testspace badge

Ready for community testing with development packages! 🚀

* refactor: improve CI/CD trigger strategy following best practices

🔧 **Workflow Trigger Improvements**

## ✅ **Removed Hard-coded Feature Branches**
- **CI Pipeline**: Only master branch + PRs (no temporary feature branches)
- **Auto Publishing**: Only master branch (stable development builds)
- **Manual Publishing**: Available from any branch when needed

## 🎯 **Benefits**
- **Maintainable**: No need to update workflows for every feature branch
- **Scalable**: Works for any future feature branches automatically
- **Clean**: CI only runs at integration points (master + PRs)
- **Efficient**: Eliminates duplicate workflow runs

## 🚀 **Result**
- ✅ Follows GitHub Actions best practices
- ✅ Reduced maintenance overhead
- ✅ Clean separation of concerns
- ✅ Ready for production use

CI/CD modernization is now production-ready! 🎉

* feat: leverage built-in Mono runtime for cross-platform .NET Framework support

🎯 **Mono Runtime Modernization**

## 📰 **Context**: Microsoft Mono Project Transition
- Original Mono Project → Moving to WineHQ stewardship
- Microsoft's modern Mono fork → Integrated into dotnet/runtime
- .NET 8+ includes built-in Mono runtime for cross-platform .NET Framework support

## ✅ **Cross-Platform .NET Framework Support**
- **Linux**: Now runs net472 tests using built-in Mono runtime
- **macOS**: Unified test execution (no more custom XUnit/Mono logic)
- **Windows**: Unchanged (native .NET Framework support)

## 🔧 **Build System Improvements**
- **Simplified Logic**: Removed platform-specific workarounds
- **Unified Execution**: Same \`dotnet test\` command across all platforms
- **Dependency Elimination**: No external Mono installation required
- **Better Coverage**: Full framework testing on all platforms

## 🚀 **CI/CD Enhancements**
- **Matrix Testing**: Added net472 to Linux/macOS matrix
- **Trigger Fix**: Added feature/* pattern for testing
- **Modern Runtime**: Leverages .NET 9.0.200 built-in Mono

## 📈 **Result**
- ✅ True cross-platform .NET Framework support
- ✅ Simplified, maintainable build system
- ✅ Zero external runtime dependencies
- ✅ Enhanced test coverage across all platforms

* feat: add Mono installation support for .NET Framework testing on Linux

* feat: add NUGET_PACKAGES environment variable to CI/CD workflows
refactor: remove redundant NuGet package installation in InitTask

* feat: update CI/CD workflows to use Ubuntu 22.04 and remove deprecated security analysis workflow

* feat: update NUGET_PACKAGES path for cross-platform compatibility and add security analysis workflow

* feat: update test execution condition for Linux and change dependency review runner to Ubuntu 22.04

* feat: remove security analysis workflow from CI/CD pipeline

* feat: add dependency review workflow for pull requests
Copy link

github-actions bot commented Jul 15, 2025

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

OpenSSF Scorecard

Scorecard details
PackageVersionScoreDetails
actions/actions/cache 4.*.* 🟢 6.2
Details
CheckScoreReason
Binary-Artifacts🟢 10no binaries found in the repo
Maintained🟢 32 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 3
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Code-Review🟢 10all changesets reviewed
Packaging⚠️ -1packaging workflow not detected
Fuzzing⚠️ 0project is not fuzzed
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection⚠️ -1internal error: error during GetBranch(releases/v1): error during branchesHandler.query: internal error: githubv4.Query: Resource not accessible by integration
SAST🟢 10SAST tool is run on all commits
Vulnerabilities🟢 82 existing vulnerabilities detected
actions/actions/checkout 4.*.* 🟢 5.2
Details
CheckScoreReason
Maintained⚠️ 01 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Packaging⚠️ -1packaging workflow not detected
Signed-Releases⚠️ -1no releases found
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
Branch-Protection⚠️ -1internal error: error during GetBranch(releases/v2): error during branchesHandler.query: internal error: githubv4.Query: Resource not accessible by integration
Security-Policy🟢 9security policy file detected
SAST🟢 8SAST tool detected but not run on all commits
Vulnerabilities⚠️ 010 existing vulnerabilities detected
actions/actions/setup-dotnet 4.*.* 🟢 5.2
Details
CheckScoreReason
Code-Review🟢 10all changesets reviewed
Maintained🟢 34 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 3
Binary-Artifacts🟢 10no binaries found in the repo
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST🟢 7SAST tool is not run on all commits -- score normalized to 7
Vulnerabilities🟢 55 existing vulnerabilities detected
actions/actions/upload-artifact 4.*.* 🟢 4.9
Details
CheckScoreReason
Maintained⚠️ 12 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
Binary-Artifacts🟢 10no binaries found in the repo
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Pinned-Dependencies⚠️ 1dependency not pinned by hash detected -- score normalized to 1
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST🟢 9SAST tool detected but not run on all commits
Vulnerabilities⚠️ 28 existing vulnerabilities detected
actions/dorny/test-reporter 1.*.* 🟢 4.3
Details
CheckScoreReason
Code-Review🟢 4Found 4/10 approved changesets -- score normalized to 4
Maintained🟢 1030 commit(s) and 21 issue activity found in the last 90 days -- score normalized to 10
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy⚠️ 0security policy file not detected
License🟢 10license file detected
Pinned-Dependencies⚠️ 2dependency not pinned by hash detected -- score normalized to 2
Fuzzing⚠️ 0project is not fuzzed
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
Vulnerabilities⚠️ 022 existing vulnerabilities detected
actions/actions/checkout 4.*.* 🟢 5.2
Details
CheckScoreReason
Maintained⚠️ 01 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Packaging⚠️ -1packaging workflow not detected
Signed-Releases⚠️ -1no releases found
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
Branch-Protection⚠️ -1internal error: error during GetBranch(releases/v2): error during branchesHandler.query: internal error: githubv4.Query: Resource not accessible by integration
Security-Policy🟢 9security policy file detected
SAST🟢 8SAST tool detected but not run on all commits
Vulnerabilities⚠️ 010 existing vulnerabilities detected
actions/actions/dependency-review-action 4.*.* 🟢 6.8
Details
CheckScoreReason
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Code-Review🟢 10all changesets reviewed
Security-Policy🟢 9security policy file detected
Packaging⚠️ -1packaging workflow not detected
Binary-Artifacts🟢 10no binaries found in the repo
Maintained🟢 1022 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Pinned-Dependencies⚠️ 2dependency not pinned by hash detected -- score normalized to 2
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection🟢 6branch protection is not maximal on development and all release branches
SAST🟢 9SAST tool detected but not run on all commits
Vulnerabilities🟢 73 existing vulnerabilities detected
actions/actions/cache 4.*.* 🟢 6.2
Details
CheckScoreReason
Binary-Artifacts🟢 10no binaries found in the repo
Maintained🟢 32 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 3
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Code-Review🟢 10all changesets reviewed
Packaging⚠️ -1packaging workflow not detected
Fuzzing⚠️ 0project is not fuzzed
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection⚠️ -1internal error: error during GetBranch(releases/v1): error during branchesHandler.query: internal error: githubv4.Query: Resource not accessible by integration
SAST🟢 10SAST tool is run on all commits
Vulnerabilities🟢 82 existing vulnerabilities detected
actions/actions/checkout 4.*.* 🟢 5.2
Details
CheckScoreReason
Maintained⚠️ 01 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Packaging⚠️ -1packaging workflow not detected
Signed-Releases⚠️ -1no releases found
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
Branch-Protection⚠️ -1internal error: error during GetBranch(releases/v2): error during branchesHandler.query: internal error: githubv4.Query: Resource not accessible by integration
Security-Policy🟢 9security policy file detected
SAST🟢 8SAST tool detected but not run on all commits
Vulnerabilities⚠️ 010 existing vulnerabilities detected
actions/actions/setup-dotnet 4.*.* 🟢 5.2
Details
CheckScoreReason
Code-Review🟢 10all changesets reviewed
Maintained🟢 34 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 3
Binary-Artifacts🟢 10no binaries found in the repo
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST🟢 7SAST tool is not run on all commits -- score normalized to 7
Vulnerabilities🟢 55 existing vulnerabilities detected
actions/actions/upload-artifact 4.*.* 🟢 4.9
Details
CheckScoreReason
Maintained⚠️ 12 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
Binary-Artifacts🟢 10no binaries found in the repo
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Pinned-Dependencies⚠️ 1dependency not pinned by hash detected -- score normalized to 1
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST🟢 9SAST tool detected but not run on all commits
Vulnerabilities⚠️ 28 existing vulnerabilities detected

Scanned Files

  • .github/workflows/ci.yml
  • .github/workflows/dependency-review.yml
  • .github/workflows/publish-dev-github.yml

@Blind-Striker Blind-Striker requested a review from Copilot July 15, 2025 19:29
Comment on lines +25 to +95
name: "Build & Test (${{ matrix.name }})"
runs-on: ${{ matrix.os }}
env:
NUGET_PACKAGES: ${{ contains(matrix.os, 'windows') && format('{0}\.nuget\packages', github.workspace) || format('{0}/.nuget/packages', github.workspace) }}

strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
name: "Windows"
script: "./build.ps1"

- os: ubuntu-22.04
name: "Linux"
script: "./build.sh"

- os: macos-latest
name: "macOS"
script: "./build.sh"

steps:
- name: "Checkout"
uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for better caching

- name: "Setup .NET SDK"
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8.0.x
9.0.x

- name: "Make build script executable"
if: runner.os != 'Windows'
run: chmod +x ./build.sh

- name: "Cache NuGet packages"
uses: actions/cache@v4
with:
path: ${{ runner.os == 'Windows' && format('{0}\.nuget\packages', github.workspace) || format('{0}/.nuget/packages', github.workspace) }}
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json', '**/*.csproj', '**/Directory.Packages.props') }}
restore-keys: |
${{ runner.os }}-nuget-

- name: "Build"
run: ${{ matrix.script }} --target build

- name: "Run Tests"
run: ${{ matrix.script }} --target tests --skipFunctionalTest ${{ runner.os == 'Linux' && 'false' || 'true' }} --exclusive

- name: "Publish Test Results"
uses: dorny/test-reporter@v1
if: success() || failure()
with:
name: 'Test Results (${{ matrix.name }})'
path: '**/TestResults/*.trx'
reporter: 'dotnet-trx'
fail-on-error: true
max-annotations: 50

- name: "Upload Test Artifacts"
uses: actions/upload-artifact@v4
if: failure()
with:
name: test-results-${{ matrix.name }}
path: |
**/*.trx
**/TestResults/**/*
retention-days: 7

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 3 days ago

To resolve the issue, we will add an explicit permissions block at the root of the workflow file. This will apply to all jobs in the workflow unless overridden by job-specific permissions. Based on the tasks performed in the workflow (e.g., checkout, caching, uploading artifacts), the minimal necessary permissions are as follows:

  • contents: read: Required for accessing repository contents.
  • actions: write: Required for uploading artifacts.

The permissions block should be added immediately after the name field in the workflow file.

Suggested changeset 1
.github/workflows/ci.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,3 +1,6 @@
+permissions:
+  contents: read
+  actions: write
 name: "CI/CD Pipeline"
 
 on:
EOF
@@ -1,3 +1,6 @@
permissions:
contents: read
actions: write
name: "CI/CD Pipeline"

on:
Copilot is powered by AI and may make mistakes. Always verify output.
@Blind-Striker Blind-Striker committed this autofix suggestion 3 days ago.
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR completes the migration from AWS SDK for .NET v3 to v4, marking the first preview release of LocalStack.NET v2.0.0. The migration introduces breaking changes including updated framework support and comprehensive package updates while maintaining API compatibility for seamless transition.

Key Changes:

  • Framework Migration: Updated from .NET Framework 4.6.2 to 4.7.2 minimum requirement
  • AWS SDK v4 Integration: Complete migration of 70+ AWS SDK packages to v4.x series with updated internal implementations
  • CI/CD Modernization: Consolidated build workflows and added GitHub Packages publishing pipeline

Reviewed Changes

Copilot reviewed 41 out of 41 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
Directory.Packages.props Updated all AWS SDK packages from v3.x to v4.x series
Multiple .csproj files Changed target framework from net462 to net472
Mock service clients Added AWS SDK v4 compatibility with new constructors and interfaces
Test implementations Fixed null-conditional operators and DynamoDB configuration updates
AwsClientFactoryWrapper.cs Migrated from non-generic ClientFactory to ClientFactory pattern
CI/CD workflows Consolidated build pipelines and added GitHub Packages automation

@@ -7,5 +7,5 @@ public static class TestConstants
public const string LocalStackV37 = "3.7.1";
public const string LocalStackV43 = "4.3.0";

public const string MovieTableMovieIdGsi = "MoiveTableMovie-Index";
public const string MovieTableMovieIdGsi = "MovieTableMovie-Index";
Copy link
Preview

Copilot AI Jul 15, 2025

Choose a reason for hiding this comment

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

Fixed spelling error in constant name from 'MoiveTableMovie-Index' to 'MovieTableMovie-Index'.

Copilot uses AI. Check for mistakes.

@@ -10,7 +10,7 @@ protected BaseDynamoDbScenario(TestFixture testFixture, ILocalStackFixture local
bool useServiceUrl = false) : base(testFixture, localStackFixture, configFile, useServiceUrl)
{
DynamoDb = ServiceProvider.GetRequiredService<IAmazonDynamoDB>();
Copy link
Preview

Copilot AI Jul 15, 2025

Choose a reason for hiding this comment

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

The migration to DynamoDBContextBuilder() introduces a more complex initialization pattern. Consider documenting this breaking change in migration guides as it affects how users initialize DynamoDB contexts.

Suggested change
DynamoDb = ServiceProvider.GetRequiredService<IAmazonDynamoDB>();
DynamoDb = ServiceProvider.GetRequiredService<IAmazonDynamoDB>();
// Breaking change: The migration to DynamoDBContextBuilder introduces a more complex initialization pattern.
// The new pattern requires using the builder to configure the DynamoDB client and build the context.
// Ensure that the DynamoDB client is correctly provided to the builder, as shown below.

Copilot uses AI. Check for mistakes.

Comment on lines +59 to +60
// Fix: Cast to Table and use GetTargetTableConfig
var targetTable = (Table)DynamoDbContext.GetTargetTable<MovieEntity>(getTargetTableConfig);
Copy link
Preview

Copilot AI Jul 15, 2025

Choose a reason for hiding this comment

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

The explicit cast to (Table) suggests a potential API design issue. Consider using a more type-safe approach or adding validation to ensure the cast is safe.

Suggested change
// Fix: Cast to Table and use GetTargetTableConfig
var targetTable = (Table)DynamoDbContext.GetTargetTable<MovieEntity>(getTargetTableConfig);
// Fix: Validate type safety and use GetTargetTableConfig
var targetTable = DynamoDbContext.GetTargetTable<MovieEntity>(getTargetTableConfig) as Table;
if (targetTable == null)
{
throw new InvalidOperationException("Failed to retrieve the target table. The returned object is not of type 'Table'.");
}

Copilot uses AI. Check for mistakes.

@@ -422,7 +424,7 @@ private async Task<Stack> WaitStackToCompleteAsync(DateTimeOffset minTimeStampFo
for (int i = events.Count - 1; i >= 0; i--)
{
var line = new StringBuilder();
line.Append(events[i].Timestamp.ToString("g", CultureInfo.InvariantCulture).PadRight(TIMESTAMP_WIDTH));
line.Append(events[i].Timestamp?.ToString("g", CultureInfo.InvariantCulture).PadRight(TIMESTAMP_WIDTH));
Copy link
Preview

Copilot AI Jul 15, 2025

Choose a reason for hiding this comment

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

The null-conditional operator on Timestamp could result in null being passed to PadRight(), which will throw an exception. Consider providing a default value: (events[i].Timestamp?.ToString("g", CultureInfo.InvariantCulture) ?? "N/A").PadRight(TIMESTAMP_WIDTH)

Suggested change
line.Append(events[i].Timestamp?.ToString("g", CultureInfo.InvariantCulture).PadRight(TIMESTAMP_WIDTH));
line.Append((events[i].Timestamp?.ToString("g", CultureInfo.InvariantCulture) ?? "N/A").PadRight(TIMESTAMP_WIDTH));

Copilot uses AI. Check for mistakes.

Comment on lines +8 to +17
private static readonly string ClientFactoryGenericTypeName = "Amazon.Extensions.NETCore.Setup.ClientFactory`1";
private static readonly string CreateServiceClientMethodName = "CreateServiceClient";

public AmazonServiceClient CreateServiceClient<TClient>(IServiceProvider provider, AWSOptions? awsOptions) where TClient : IAmazonService
{
Type? clientFactoryType = typeof(ConfigurationException).Assembly.GetType(ClientFactoryFullName);
Type? genericFactoryType = typeof(ConfigurationException).Assembly.GetType(ClientFactoryGenericTypeName);

if (clientFactoryType == null)
if (genericFactoryType == null)
{
throw new LocalStackClientConfigurationException($"Failed to find internal ClientFactory in {ClientFactoryFullName}");
throw new LocalStackClientConfigurationException($"Failed to find internal ClientFactory<T> in {ClientFactoryGenericTypeName}");
Copy link
Preview

Copilot AI Jul 15, 2025

Choose a reason for hiding this comment

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

Using hardcoded type names with reflection is fragile and could break with future AWS SDK updates. Consider using a more robust approach such as searching for types that implement expected interfaces or using typeof() where possible.

Copilot uses AI. Check for mistakes.

@@ -11,5 +17,12 @@ public MockClientConfig()

public override string UserAgent => InternalSDKUtils.BuildUserAgentString(ServiceVersion);

public override Endpoint DetermineServiceOperationEndpoint(ServiceOperationEndpointParameters parameters)
Copy link
Preview

Copilot AI Jul 15, 2025

Choose a reason for hiding this comment

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

The method ignores the 'parameters' argument and always returns a hardcoded endpoint. Consider validating the parameters or at least adding a comment explaining why they are ignored in mock scenarios.

Copilot uses AI. Check for mistakes.

Blind-Striker and others added 4 commits July 15, 2025 22:49
…n permissions

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
…sole integration

- ✨ Add dynamic version generation from Directory.Build.props
  - Support --use-directory-props-version flag for automated CI/CD builds
  - Extract PackageMainVersion and PackageExtensionVersion properties
  - Generate build metadata with date, commit SHA, and branch name
  - NuGet-compliant version format: 2.0.0-preview1-20250716-080214

- �� Integrate Spectre.Console for rich developer experience
  - Beautiful FigletText headers with LocalStack.NET branding
  - Color-coded status messages (✅ success, ⚠️ warnings, ❌ errors)
  - Rich package information tables with rounded borders
  - Progress bars for package creation and publishing operations
  - Publication summary panels with download URLs

- 🏗️ Refactor NugetPackTask with multi-package support
  - Support packing all packages when no specific ID provided
  - Eliminate magic strings with centralized constants
  - Use existing GetProjectTargetFrameworks methods instead of hardcoded values
  - Enhanced PrepareExtensionsProject with Cake built-in methods
  - Improved validation with dynamic version support

- 🚀 Enhance NugetPushTask with better feedback
  - Rich console output for publishing operations
  - Dynamic version support for automated workflows
  - Upload progress indication and status reporting
  - Package URL generation for different sources

- 🔧 Modernize BuildContext with enhanced capabilities
  - Add package/source constants (LocalStackClientProjName, GitHubPackageSource)
  - Implement GetPackageTargetFrameworks for better target framework handling
  - Add UseDirectoryPropsVersion and BranchName properties
  - Robust git commit SHA extraction with fallback
  - Default package source to github for better CI/CD integration

- 📦 Replace manual process execution with Cake built-in methods
  - Use context.DotNetRemoveReference() instead of process calls
  - Use context.DotNetAddPackage() for package reference management
  - Proper working directory management and error handling
  - Type-safe FilePath handling for better reliability

BREAKING CHANGE: Enhanced build system now defaults to github package source.
Use --package-source flag to specify different targets.

Implements Phases 1-4 of Cake Build Enhancement Plan.
Maintains backward compatibility with existing workflows.
Eliminates bash version generation complexity.
Provides foundation for GitHub Actions workflow simplification.
🚀 Complete Cake build system modernization with Spectre.Console integration and GitHub workflow simplification

**Phase 5: New SummaryTask Implementation**
- Add SummaryTask.cs with rich Spectre.Console output
- Beautiful build completion panels with package information
- Dynamic installation instructions for GitHub Packages vs NuGet.org
- Comprehensive build metadata table with version source, timestamps, frameworks
- Culture-invariant string formatting for international compatibility

**Phase 6: GitHub Workflow Simplification**
- Replace bash version generation with Cake dynamic versioning
- Eliminate complex bash scripts with --use-directory-props-version flag
- Add nuget-pack-and-publish convenience task for streamlined operations
- Update publish-dev-github.yml to use enhanced Cake build system
- Replace manual package dependency switching with Cake built-in methods

**Developer Experience Enhancements**
- Rich console output with progress bars, tables, and colored status messages
- Dynamic version generation: 2.0.0-preview1-feature-v2-preview1-20250716-081604
- Centralized constants eliminate magic strings throughout codebase
- Professional publication-ready build system with beautiful visual feedback

**Technical Improvements**
- All StringBuilder operations use CultureInfo.InvariantCulture for consistency
- DateTime formatting with invariant culture for international environments
- Eliminated reflection-based private method access for better maintainability
- Comprehensive error handling with graceful fallbacks

**Workflow Simplification Results**
- Before: 20+ lines of complex bash version generation logic
- After: Single --use-directory-props-version flag with automatic handling
- Reduced GitHub Actions complexity while maintaining full functionality
- Enhanced local development experience with rich console feedback

Completes enhancement plan phases 1-6. Build system now provides beautiful developer experience with centralized logic, dynamic versioning, and simplified CI/CD workflows.

BREAKING CHANGE: None - all changes maintain backward compatibility with existing --package-version workflows
@Blind-Striker Blind-Striker merged commit 2ea6c23 into master Jul 16, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant