diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..5feb563ec4 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,109 @@ +name: CI Build + +on: + push: + branches: + - master + - 'release/**' + - 'maintenance/**' + paths-ignore: + - '**/*.png' + - '**/*.md' + workflow_dispatch: + +env: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + DOTNET_CLI_TELEMETRY_OPTOUT: true + +jobs: + build-and-test: + name: Build & Test + runs-on: windows-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 1 + lfs: true + + - name: Setup .NET SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: | + 6.0.x + 8.0.x + + - name: Setup .NET nanoFramework build components + uses: nanoframework/nanobuild@v1 + with: + workload: 'nanoFramework' + + - name: Build, Test and Pack + shell: pwsh + run: | + ./Build/build.ps1 -IncludeNanoFramework + working-directory: ${{ github.workspace }} + + - name: Upload to codecov.io + shell: pwsh + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + run: | + Write-Host -Foreground Green "Downloading codecov binaries..." + + Invoke-WebRequest -Uri https://uploader.codecov.io/verification.gpg -OutFile codecov.asc + gpg.exe --import codecov.asc + + Invoke-WebRequest -Uri https://uploader.codecov.io/latest/windows/codecov.exe -Outfile codecov.exe + Invoke-WebRequest -Uri https://uploader.codecov.io/latest/windows/codecov.exe.SHA256SUM -Outfile codecov.exe.SHA256SUM + Invoke-WebRequest -Uri https://uploader.codecov.io/latest/windows/codecov.exe.SHA256SUM.sig -Outfile codecov.exe.SHA256SUM.sig + + gpg.exe --verify codecov.exe.SHA256SUM.sig codecov.exe.SHA256SUM + If ($(Compare-Object -ReferenceObject $(($(certUtil -hashfile codecov.exe SHA256)[1], "codecov.exe") -join " ") -DifferenceObject $(Get-Content codecov.exe.SHA256SUM)).length -eq 0) { echo "SHASUM verified" } Else {exit 1} + + Write-Host -Foreground Green "Uploading to codecov..." + + .\codecov.exe --dir "Artifacts/Coverage" -t "$env:CODECOV_TOKEN" --build "${{ github.run_number }}" + + Write-Host -Foreground Green "✅ Uploaded to codecov." + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: artifacts + path: Artifacts/ + retention-days: 30 + + - name: Upload NuGet packages + uses: actions/upload-artifact@v4 + with: + name: nuget-packages + path: | + Artifacts/**/*.nupkg + Artifacts/**/*.snupkg + retention-days: 30 + + publish-nuget: + name: Publish to NuGet + needs: build-and-test + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/master' && github.repository_owner == 'angularsen' + environment: Publish + + steps: + - name: Download NuGet packages + uses: actions/download-artifact@v4 + with: + name: nuget-packages + path: nugets + + - name: Setup .NET SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + + - name: Push to nuget.org + run: | + dotnet nuget push "**/*.nupkg" --skip-duplicate --api-key ${{ secrets.NUGET_ORG_APIKEY }} --source https://api.nuget.org/v3/index.json + working-directory: nugets \ No newline at end of file diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000000..b619c7ae0f --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,93 @@ +name: PR Build + +on: + pull_request: + branches: + - master + - 'release/**' + - 'maintenance/**' + paths-ignore: + - '*.md' + - '*.png' + - '*.gitignore' + +env: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + DOTNET_CLI_TELEMETRY_OPTOUT: true + +jobs: + build-and-test: + name: Build & Test + runs-on: windows-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 1 + lfs: true + + - name: Setup .NET SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: | + 6.0.x + 8.0.x + + - name: Setup .NET nanoFramework build components + uses: nanoframework/nanobuild@v1 + with: + workload: 'nanoFramework' + + - name: Build, Test and Pack + shell: pwsh + run: | + ./Build/build.ps1 -IncludeNanoFramework + working-directory: ${{ github.workspace }} + + - name: Upload Test Results + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-results + path: Artifacts/TestResults/*.trx + retention-days: 7 + + - name: Publish Test Results + uses: EnricoMi/publish-unit-test-result-action/windows@v2 + if: always() + with: + files: | + Artifacts/TestResults/*.trx + check_name: Test Results + comment_mode: off + + - name: Upload to codecov.io + shell: pwsh + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + run: | + Write-Host -Foreground Green "Downloading codecov binaries..." + + Invoke-WebRequest -Uri https://uploader.codecov.io/verification.gpg -OutFile codecov.asc + gpg.exe --import codecov.asc + + Invoke-WebRequest -Uri https://uploader.codecov.io/latest/windows/codecov.exe -Outfile codecov.exe + Invoke-WebRequest -Uri https://uploader.codecov.io/latest/windows/codecov.exe.SHA256SUM -Outfile codecov.exe.SHA256SUM + Invoke-WebRequest -Uri https://uploader.codecov.io/latest/windows/codecov.exe.SHA256SUM.sig -Outfile codecov.exe.SHA256SUM.sig + + gpg.exe --verify codecov.exe.SHA256SUM.sig codecov.exe.SHA256SUM + If ($(Compare-Object -ReferenceObject $(($(certUtil -hashfile codecov.exe SHA256)[1], "codecov.exe") -join " ") -DifferenceObject $(Get-Content codecov.exe.SHA256SUM)).length -eq 0) { echo "SHASUM verified" } Else {exit 1} + + Write-Host -Foreground Green "Uploading to codecov..." + + .\codecov.exe --dir "Artifacts/Coverage" -t "$env:CODECOV_TOKEN" --build "${{ github.run_number }}" + + Write-Host -Foreground Green "✅ Uploaded to codecov." + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: artifacts + path: Artifacts/ + retention-days: 7 \ No newline at end of file diff --git a/GITHUB_ACTIONS_MIGRATION_README.md b/GITHUB_ACTIONS_MIGRATION_README.md new file mode 100644 index 0000000000..9d19216a7a --- /dev/null +++ b/GITHUB_ACTIONS_MIGRATION_README.md @@ -0,0 +1,44 @@ +# GitHub Actions Migration + +This PR adds GitHub Actions workflows to run alongside the existing Azure Pipelines configuration. + +## Files to Move + +Due to GitHub App permission restrictions, the workflow files are created in the root directory. Please move these files to `.github/workflows/` after merging: + +1. `github-actions-ci.yml` → `.github/workflows/ci.yml` +2. `github-actions-pr.yml` → `.github/workflows/pr.yml` + +## Key Features + +### CI Workflow (ci.yml) +- Triggers on pushes to master, release/*, and maintenance/* branches +- Builds with .NET nanoFramework support using `nanoframework/nanobuild@v1` action +- Runs tests and uploads coverage to codecov.io +- Publishes NuGet packages to nuget.org (only on master branch) +- Uses Windows runner to match Azure Pipelines configuration + +### PR Workflow (pr.yml) +- Triggers on pull requests to master, release/*, and maintenance/* branches +- Same build and test process as CI workflow +- Publishes test results as PR checks +- Uploads test coverage to codecov.io +- No NuGet publishing for PRs + +## .NET nanoFramework Support + +The key challenge mentioned in the issue was .NET nanoFramework support. This is handled using the `nanoframework/nanobuild@v1` GitHub Action, which is the official GitHub Actions equivalent of the Azure Pipelines `InstallNanoMSBuildComponents@1` task. + +## Migration Notes + +- Both workflows use the existing PowerShell build script (`Build/build.ps1`) with the `-IncludeNanoFramework` flag +- Secrets needed: `CODECOV_TOKEN` and `NUGET_ORG_APIKEY` (should already be configured) +- The workflows are designed to run alongside Azure Pipelines for comparison +- Azure Pipelines configuration files remain unchanged as requested + +## Next Steps + +1. Move the workflow files to `.github/workflows/` +2. Test both workflows to ensure they work correctly +3. Compare results with Azure Pipelines +4. Make any necessary adjustments based on testing \ No newline at end of file