I'm trying to configure a GitHub action that builds my multi-target Xamarin.Forms plugin and pushes the package to GitHub and NuGet. Pushing the package to GitHub and NuGet shouldn't be much of a problem anymore. I'm having trouble with building my multi-targeted nuget package on the GitHub CI.
First I had the following GitHub action:
name: .NET Core
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout#v2
- name: Setup .NET Core
uses: actions/setup-dotnet#v1.5.0
with:
dotnet-version: 3.1.301
# Authenticates packages to push to GPR
source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
env:
NUGET_AUTH_TOKEN: '%NUGET_AUTH_TOKEN%'
- name: Install dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Test
run: dotnet test --no-restore --verbosity normal
- name: Pack
run: dotnet pack --no-build --configuration Release MintPlayer.MVVM/MintPlayer.MVVM.csproj --output .
- name: PushNuget
run: dotnet nuget push *.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.PUBLISH_TO_NUGET_ORG }} --skip-duplicate
- name: PushGithub
#run: dotnet nuget push *.nupkg --source https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json --api-key ${{ github.token }} --no-symbols --skip-duplicate
run: dotnet nuget push *.nupkg --no-symbols --skip-duplicate
env:
NUGET_AUTH_TOKEN: ${{ github.token }}
and also the following nuget.config in my solution root, to let the action know about the nuget source to download the required NuGet packages:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
</packageSources>
</configuration>
When pushing this configuration to my GitHub repository, I'm getting the following errors at the Build stage:
/Users/runner/work/MintPlayer.MVVM/MintPlayer.MVVM/Demo/MintPlayer.MVVM.Demo/MintPlayer.MVVM.Demo.UWP/MintPlayer.MVVM.Demo.UWP.csproj(175,3): error MSB4019: The imported project "/Users/runner/hostedtoolcache/dncs/3.1.301/x64/sdk/3.1.301/Microsoft/WindowsXaml/v16.0/Microsoft.Windows.UI.Xaml.CSharp.targets" was not found. Confirm that the expression in the Import declaration "/Users/runner/hostedtoolcache/dncs/3.1.301/x64/sdk/3.1.301//Microsoft/WindowsXaml/v16.0/Microsoft.Windows.UI.Xaml.CSharp.targets" is correct, and that the file exists on disk.
/Users/runner/work/MintPlayer.MVVM/MintPlayer.MVVM/Demo/MintPlayer.MVVM.Demo/MintPlayer.MVVM.Demo.iOS/MintPlayer.MVVM.Demo.iOS.csproj(140,3): error MSB4019: The imported project "/Users/runner/hostedtoolcache/dncs/3.1.301/x64/sdk/3.1.301/Xamarin/iOS/Xamarin.iOS.CSharp.targets" was not found. Confirm that the expression in the Import declaration "/Users/runner/hostedtoolcache/dncs/3.1.301/x64/sdk/3.1.301//Xamarin/iOS/Xamarin.iOS.CSharp.targets" is correct, and that the file exists on disk.
/Users/runner/work/MintPlayer.MVVM/MintPlayer.MVVM/Demo/MintPlayer.MVVM.Demo/MintPlayer.MVVM.Demo.Android/MintPlayer.MVVM.Demo.Android.csproj(101,3): error MSB4019: The imported project "/Users/runner/hostedtoolcache/dncs/3.1.301/x64/sdk/3.1.301/Xamarin/Android/Xamarin.Android.CSharp.targets" was not found. Confirm that the expression in the Import declaration "/Users/runner/hostedtoolcache/dncs/3.1.301/x64/sdk/3.1.301//Xamarin/Android/Xamarin.Android.CSharp.targets" is correct, and that the file exists on disk.
I then modified my workflow to use msbuild instead (at least until the build stage:
name: .NET Core
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout#v2
- name: Setup .NET Core
uses: actions/setup-dotnet#v1.5.0
with:
dotnet-version: 3.1.301
# Authenticates packages to push to GPR
source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
env:
NUGET_AUTH_TOKEN: '%NUGET_AUTH_TOKEN%'
- name: Install dependencies
#run: dotnet restore
#env:
# NUGET_AUTH_TOKEN: ${{ github.token }}
run: msbuild /t:restore
- name: Build
#run: dotnet build --configuration Release --no-restore
run: msbuild Library/MintPlayer.MVVM/MintPlayer.MVVM.csproj /p:Configuration=Release /p:RestorePackages=false
- name: Test
run: dotnet test --no-restore --verbosity normal
- name: Pack
run: dotnet pack --no-build --configuration Release MintPlayer.MVVM/MintPlayer.MVVM.csproj --output .
- name: PushNuget
run: dotnet nuget push *.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.PUBLISH_TO_NUGET_ORG }} --skip-duplicate
- name: PushGithub
#run: dotnet nuget push *.nupkg --source https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json --api-key ${{ github.token }} --no-symbols --skip-duplicate
run: dotnet nuget push *.nupkg --no-symbols --skip-duplicate
env:
NUGET_AUTH_TOKEN: ${{ github.token }}
But it's still not working.
The console in Github actions prints the following error between the tons of text:
/Users/runner/.nuget/packages/msbuild.sdk.extras/2.1.2/Build/LanguageTargets/CheckMissing.targets(44,5): error : The specified language targets for uap10.0.16299 is missing. Ensure correct tooling is installed for 'uap'. Missing: '/Library/Frameworks/Mono.framework/Versions/6.12.0/lib/mono/xbuild/Microsoft/WindowsXaml/v16.0/Microsoft.Windows.UI.Xaml.CSharp.targets' [/Users/runner/work/MintPlayer.MVVM/MintPlayer.MVVM/Library/MintPlayer.MVVM/MintPlayer.MVVM.csproj]
So this probably means that the UWP tools aren't available on macos. From the output I can see that the android build succeeds, the iOS build succeeds, but the UWP build fails with the former message.
How can I build a Xamarin.Forms package in GitHub CI and push it to my nuget sources?
Edit:
Alright, I modified my workflow to use Windows and MSBuild instead of macos and dotnet, and this brings me a lot closer.
name: .NET Core
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout#v2
- name: Setup .NET Core
uses: actions/setup-dotnet#v1.5.0
with:
dotnet-version: 3.1.301
# Authenticates packages to push to GPR
source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
env:
NUGET_AUTH_TOKEN: '%NUGET_AUTH_TOKEN%'
# Add MsBuild to the PATH: https://github.com/microsoft/setup-msbuild
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild#v1.0.1
- name: Install dependencies
run: msbuild /t:restore
env:
NUGET_AUTH_TOKEN: ${{ github.token }}
- name: Build
run: msbuild Library/MintPlayer.MVVM/MintPlayer.MVVM.csproj /p:Configuration=Release /p:RestorePackages=false /p:OutputPath=../..
- name: PushNuget
run: dotnet nuget push *.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.PUBLISH_TO_NUGET_ORG }} --skip-duplicate
- name: PushGithub
run: dotnet nuget push *.nupkg --no-symbols --skip-duplicate
env:
NUGET_AUTH_TOKEN: ${{ github.token }}
This action successfully pushes my nuget package to both Nuget and Github, but when I install this package in a Xamarin.Forms project, I'm only getting the UWP classes available in all of the projects, whilst these should only be available in the UWP-targetting project.
Unlike when I right-click my multi-targetting project and click the Pack command, the package does in fact work fine. Does anyone know how I can fix this?
This is my final workflow:
name: .NET Core
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout#v2
- name: Setup .NET Core
uses: actions/setup-dotnet#v1.7.2
with:
dotnet-version: 3.1.301
# Authenticates packages to push to GPR
source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
env:
NUGET_AUTH_TOKEN: '%NUGET_AUTH_TOKEN%'
- name: Setup MSBuild
uses: microsoft/setup-msbuild#v1.0.2
- name: Install dependencies
run: msbuild /t:Restore
env:
NUGET_AUTH_TOKEN: ${{ github.token }}
- name: Build
run: |
msbuild /t:Pack /p:Configuration=Debug Library/MintPlayer.MVVM/MintPlayer.MVVM.csproj
dotnet pack Library\MintPlayer.MVVM.BaseModel\MintPlayer.MVVM.BaseModel.csproj --configuration=Release
- name: PushNuget
run: dotnet nuget push "**/*.nupkg" --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.PUBLISH_TO_NUGET_ORG }} --skip-duplicate
- name: PushGithub
run: nuget.exe push "**/*.nupkg" -NoSymbols -SkipDuplicate
env:
NUGET_AUTH_TOKEN: ${{ github.token }}
Related
a Github Actions workflow stopped working throwing a 401 error when publishing a repo's package to the Github package registry. Within the workflow (detailed below) I am using semantic-release to publish the artefact to the registry. This is the last step in the yml. The permissions for the GITHUB_TOKEN have not been changed since initial setup of the action. It used to run just fine with these permissions.
./github/workflow.yml
name: ci
on:
push:
branches: [ main, dev ]
paths:
- src/**
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
issues: write
steps:
- uses: actions/checkout#v3
- uses: actions/setup-dotnet#v2
with:
dotnet-version: '6.x.x'
- name: Build that shit
run: dotnet build ./src/project.csproj --configuration Release --nologo
- uses: actions/setup-node#v3
with:
node-version: 'lts/*'
- name: Release that shit
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm ci && npx semantic-release
The GITHUB_TOKEN is mapped to an environment variable GH_TOKEN which then is referenced by semantic-release in the publishCmd.
./.releaserc
{
"branches": [
"main",
{
"name": "dev",
"prerelease": "dev"
}
],
"plugins": [
"#semantic-release/commit-analyzer",
"#semantic-release/release-notes-generator",
"#semantic-release/github",
[
"#semantic-release/exec", {
"prepareCmd": "dotnet pack ./src/project.csproj --no-restore --nologo --configuration Release /p:Version=${nextRelease.version}",
"publishCmd": "dotnet nuget push ./src/bin/Release/project.${nextRelease.version}.nupkg --source https://nuget.pkg.github.com/MY_ORG/index.json --api-key ${process.env.GH_TOKEN}"
}
]
]
}
The logs show the last step failing
[11:05:13 AM] [semantic-release] › ℹ Start step "publish" of plugin "#semantic-release/exec"
[11:05:13 AM] [semantic-release] [#semantic-release/exec] › ℹ Call script dotnet nuget push ./src/bin/Release/project.2.8.6.nupkg --source https://nuget.pkg.github.com/MY_ORG/index.json --api-key [secure]
error: Unable to load the service index for source https://nuget.pkg.github.com/MY_ORG/index.json.
error: Response status code does not indicate success: 401 (Unauthorized).
This is a repo owned by the organization I am employed with. There are no dependencies to private packages registries, only public NUGET. So the GITHUB_TOKEN should suffice according to the docs. And also according to previous successful execution history.
Does someone spot something I am missing?
The only way I made this work again on GH is using a PAT.
Created a PAT in my user/developer settings
Added a secret in my repo called NUGET_PAT
Updated my yaml file to this
name: "Push to main"
on:
push:
tags:
- '*'
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- uses: actions/setup-dotnet#v3
with:
dotnet-version: '7.0.x'
- name: Add source
run: |
dotnet nuget add source \
--username THE_USER_OWNER_OF_THE_PAT --password "${{ secrets.NUGET_PAT }}" \
--store-password-in-clear-text --name github "https://nuget.pkg.github.com/YOUR_ORG/index.json"
- name: Restore packages
run: dotnet restore
- name: Build
run: dotnet build --configuration Release -p:Version=${{github.ref_name}} --no-restore
- name: Run tests
run: dotnet test --configuration Release --no-restore --no-build --verbosity normal
- name: Create nuget packages
run: dotnet pack --configuration Release -p:Version=${{github.ref_name}} --no-restore --no-build
- name: Publish nuget packages
run: dotnet nuget push **/*.nupkg -s "https://nuget.pkg.github.com/YOUR_ORG/index.json"
It pushes with warnings
I have a dotnet project and am trying to build a CI/CD pipeline that does the following using Github Actions:
Builds the project on a PR or master change.
Tests the project on a PR or master change.
On a master change calculates a semver (ideally a changelog too but that's less important).
On a master change uses this semver, builds a nuget package, and publishes it to GitHub and Nuget.
So far, I have this workflow that builds and tests my project. This seems to work nicely. However, it also has a publish step, which never seems to be run (I guess the if is wrong(?)) and I'm really not sure where to start with the SemVer part of what I want.
name: .NET Build, Test and Publish
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
env:
DISCOS_API_KEY: ${{ secrets.DISCOS_API_KEY }}
DISCOS_API_URL: http://localhost:3000/api/
steps:
- uses: actions/checkout#v2
with:
submodules: recursive
- name: Build docker stack
run: docker-compose -f src/DISCOSweb-Sdk/DISCOSweb-Sdk.Tests/docker-compose.yml up -d --force-recreate --build
- name: Setup .NET
uses: actions/setup-dotnet#v1
with:
dotnet-version: 6.0.x
- name: Restore dependencies
run: dotnet restore src/DISCOSweb-Sdk/DISCOSweb-Sdk.sln
- name: Build
run: dotnet build --no-restore src/DISCOSweb-Sdk/DISCOSweb-Sdk.sln
- name: Test
run: dotnet test --no-build --verbosity normal src/DISCOSweb-Sdk/DISCOSweb-Sdk.sln
publish: # This stage is never run
if: github.event.pull_request.merged == 'true'
needs: build
runs-on: ubuntu-latest
steps:
- name: Publish
id: publish_nuget
uses: brandedoutcast/publish-nuget#v2
with:
PACKAGE_NAME: DISCOSweb-Sdk
PROJECT_FILE_PATH: "**/DISCOSweb-Sdk.csproj"
BUILD_CONFIGURATION: Release
NUGET_KEY: ${{secrets.NUGET_KEY}}
VERSION_STATIC: 1.0.0 # Replace with something better
I feel like this should be a relatively common and straightforward thing to do so any assistance would be really appreciated.
I managed to accomplish this by splitting my CI and CD workflows, and making use of some very helpful packages.
CI Workflow
This first workflow runs on PRs and pushes to master. It's worth noting that when branch protection is on, a push to master is synonymous with a merged PR.
name: .NET Continuous Integration
on:
pull_request:
branches: [ master ]
push:
branches: [ master ]
jobs:
test:
name: Test Project (Mock API)
runs-on: ubuntu-latest
env:
DISCOS_API_KEY: ${{ secrets.DISCOS_API_KEY }}
DISCOS_API_URL: http://localhost:3000/api/
steps:
- uses: actions/checkout#v3
- name: Setup .NET
uses: actions/setup-dotnet#v2
with:
dotnet-version: 6.0.x
- name: Build docker stack
run: docker-compose -f ./src/DiscosWebSdk/DiscosWebSdk.Tests/docker-compose.yml up -d --force-recreate --build
- name: Run tests against mock API
run: dotnet test --logger GitHubActions ./src/DiscosWebSdk/DiscosWebSdk.sln
CD Workflow
There's a bit more to the CD workflow. It runs on pushes to master but only when there are changes made to the folder containing the actual source code for the SDK (that's what the paths block does).
I then used the mathieudutour/github-tag-action#v6.0 action to tag the commit with a calculated semantic version (calculated using conventional commits).
The package build is then tagged with this version using the -p:PackageVersion=${{ steps.tag_version.outputs.new_version }} option on dotnet nuget pack.
The ncipollo/release-action#v1 also creates a release on Github.
Finally, building and pushing the release to Github and Nuget is done using dotnet nuget push as usual.
name: .NET Continuous Deployment
on:
push:
branches: [ master ]
paths:
- src/DiscosWebSdk/DiscosWebSdk/**
workflow_dispatch:
jobs:
test:
name: Test Project (Real API)
runs-on: ubuntu-latest
env:
DISCOS_API_KEY: ${{ secrets.DISCOS_API_KEY }}
DISCOS_API_URL: https://discosweb.esoc.esa.int/api/
steps:
- uses: actions/checkout#v3
- name: Setup .NET
uses: actions/setup-dotnet#v2
with:
dotnet-version: 6.0.x
- name: Test against real API
run: dotnet test --logger GitHubActions ./src/DiscosWebSdk/DiscosWebSdk.sln
semantic-release:
needs: test
name: Create a Package Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3 # Need the full commit history for conventional commit
- name: Setup .NET
uses: actions/setup-dotnet#v2
with:
dotnet-version: 6.0.x
- name: Bump version and push tag
id: tag_version
uses: mathieudutour/github-tag-action#v6.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Create a GitHub release
uses: ncipollo/release-action#v1
with:
tag: ${{ steps.tag_version.outputs.new_tag }}
name: Release ${{ steps.tag_version.outputs.new_tag }}
body: ${{ steps.tag_version.outputs.changelog }}
- name: Create Nuget Package
run: dotnet build -c Release ./src/DiscosWebSdk/DiscosWebSdk/DiscosWebSdk.csproj && dotnet pack -c Release -p:PackageVersion=${{ steps.tag_version.outputs.new_version }} -o . ./src/DiscosWebSdk/DiscosWebSdk/DiscosWebSdk.csproj
- name: Upload Package for Publishing
uses: actions/upload-artifact#v3
with:
name: PackedLib
path: ./*.nupkg
github-publish:
needs: semantic-release
name: Publish to Github
runs-on: ubuntu-latest
steps:
- name: Download built project
uses: actions/download-artifact#v3
with:
name: PackedLib
- name: Setup .NET
uses: actions/setup-dotnet#v2
with:
dotnet-version: 6.0.x
- name: Push Package to GitHub
run: dotnet nuget push --api-key ${{secrets.GITHUB_TOKEN}} --source "https://nuget.pkg.github.com/hughesjs/index.json" *.nupkg
nuget-publish:
needs: semantic-release
name: Publish to Nuget
runs-on: ubuntu-latest
steps:
- name: Download built project
uses: actions/download-artifact#v3
with:
name: PackedLib
- name: Setup .NET
uses: actions/setup-dotnet#v2
with:
dotnet-version: 6.0.x
- name: Push Package to Nuget
run: dotnet nuget push --api-key ${{secrets.NUGET_KEY}} --source "https://api.nuget.org/v3/index.json" *.nupkg
I recently tried automatically building and uploading my C# project. The build works fine, but the artifact sadly only contains a DLL file, and not a .exe file. When I build it locally, it outputs an .exe and a DLL file. Is that normal? This is my github actions file:
name: .NET
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
name: Build the app
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
- name: Setup .NET
uses: actions/setup-dotnet#v2
with:
dotnet-version: 6.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build
- name: Upload a Build Artifact
uses: actions/upload-artifact#v2.2.2
with:
# Artifact name
name: buildresult #.zip will be added automatically
path: /home/runner/work/ParadoxicalLauncher/ParadoxicalLauncher/ParadoxicalLauncher/bin/Debug/net6.0/*.*
I'm trying to publish 3 projects as a nuget package. The following GitHub workflow works fine publishing Project1, but it doesn't publish src/Project2/Project2.csproj and src/Project3/Project3.csproj.
I tried to create 3 files with the exact same code but for each one of the projects and there is a conflict in versionize. The first project is being published just fine but the rest of them fail because of the versions.
How can I make it work that way?
name: Publish
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
with:
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet#v2
with:
dotnet-version: 6.0.x
source-url: https://nuget.pkg.github.com/Xnt/index.json
env:
NUGET_AUTH_TOKEN: ${{ secrets.PERSONAL_GITHUB_TOKEN }}
- name: Install dotnet tools
run: dotnet tool install --global Versionize
- name: Restore
run: dotnet restore
- name: Build
run: dotnet build -c Release --no-restore
- name: Setup git
run: |
git config --global user.name 'GitHub actions'
git config --global user.email '...'
- name: Version
run: versionize
- name: Push tags
run: |
git push --follow-tags
- name: Pack
run: dotnet pack --no-build -c Release -o . src/Project1/Project1.csproj
- name: Publish
run: dotnet nuget push *.nupkg
when i push the code to github, and create the file workflow\dotnet.yml.
name: dotnet package
on: [push]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
dotnet-version: ['5.0.x' ]
steps:
- uses: actions/checkout#v3
- name: Setup .NET Core SDK ${{ matrix.dotnet-version }}
uses: actions/setup-dotnet#v2
with:
dotnet-version: ${{ matrix.dotnet-version }}
- name: Install dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Test
run: dotnet test --no-restore --verbosity normal
In the Actions output, the following error is shown.
The framework 'Microsoft.NETCore.App', version '3.1.0' was not found.
The following frameworks were found: 5.0.17 at [/home/runner/.dotnet/shared/Microsoft.NETCore.App]
Followed the link, and installed the frameworks, but it still errors. Can anyone provide help with this?