ios.netgithub-actionsmauicontinuous-deployment

Github Actions .NET MAUI iOS publish error: No valid iOS code signing keys found in keychain


I have a .net8.0 maui application that I am trying to upload to testflight via github actions with xcode 16. I have created a new signing certificate and an Apple Store provisioning profile that uses that certificate. I'm using Steven Thewessen's workflow from this guide, but I'm getting this error from my dotnet publish step:

- name: Build iOS
        run: dotnet publish ${{ inputs.project-file }} -c ${{ inputs.build-config }} -f ${{ inputs.dotnet-version-target}}-ios /p:ArchiveOnBuild=true --no-restore

/Users/runner/.dotnet/packs/Microsoft.iOS.Sdk.net8.0_18.0/18.0.8319/tools/msbuild/iOS/Xamarin.Shared.targets(1835,3): error : No valid iOS code signing keys found in keychain. You need to request a codesigning certificate from https://developer.apple.com. [/Users/runner/work/App/App/App/App.csproj::TargetFramework=net8.0-ios]
/Users/runner/.dotnet/packs/Microsoft.iOS.Sdk.net8.0_18.0/18.0.8319/tools/msbuild/iOS/Xamarin.Shared.targets(1835,3): error :          [/Users/runner/work/App/App/App/App.csproj::TargetFramework=net8.0-ios]

This is my cd-ios.yml workflow (without all the inputs from my cd-build.yml):

name: iOS Publish

jobs:
  publish-ios:
    runs-on: macos-latest

    steps:
      - uses: maxim-lobanov/setup-xcode@v1
        name: Set XCode version
        with:
          xcode-version: ${{ inputs.xcode-version }}

      - name: Import iOS Certs
        uses: apple-actions/import-codesign-certs@v3
        with:
          p12-file-base64: ${{ secrets.dist-cert-p12 }}
          p12-password: ${{ secrets.dist-cert-password }}
      
      - name: Download Provisioning Profiles
        id: provisioning
        uses: apple-actions/download-provisioning-profiles@v1
        with: 
          bundle-id: ${{ inputs.package-name }}
          profile-type: 'IOS_APP_STORE'
          issuer-id: ${{ secrets.appstore-issuer }}
          api-key-id: ${{ secrets.appstore-keyid }}
          api-private-key: ${{ secrets.appstore-private-key }}

      - name: List Certificates
        run: security find-identity -v -p codesigning

      - name: List Downloaded Provisioning Profiles
        run: ls -lah ~/Library/MobileDevice/Provisioning\ Profiles/
    
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Setup .NET ${{ inputs.dotnet-version }}
        uses: actions/setup-dotnet@v3
        with:
          dotnet-version: ${{ inputs.dotnet-version }}

      - name: Install MAUI Workloads
        run: dotnet workload install maui

      - name: Restore NuGet Packages
        run: dotnet restore ${{ inputs.sln-file }} --configfile ${{ inputs.nuget-config }}
        env:
          TELERIK_NUGET_KEY: ${{ secrets.telerik-nuget-api-key }}

      - name: Version the app
        uses: managedcode/MAUIAppVersion@v1
        with:
          csproj: ${{ inputs.project-file }}
          version: ${{ github.run_number }}
          displayVersion: ${{ inputs.build-version }}.${{ github.run_number }}
          printFile: true

      - name: Build iOS
        run: dotnet publish ${{ inputs.project-file }} -c ${{ inputs.build-config }} -f ${{ inputs.dotnet-version-target}}-ios /p:ArchiveOnBuild=true --no-restore

      - name: Upload app to TestFlight
        uses: apple-actions/upload-testflight-build@v1
        with:
          app-path: ${{ github.workspace }}/${{ inputs.project-folder }}/bin/${{ inputs.build-config }}/${{ inputs.dotnet-version-target}}-ios/ios-arm64/publish/*.ipa
          issuer-id: ${{ secrets.appstore-issuer }}
          api-key-id: ${{ secrets.appstore-keyid }}
          api-private-key: ${{ secrets.appstore-private-key }}

The step downloading my provisioning profiles returns this:

Run apple-actions/download-provisioning-profiles@v1
Wrote IOS_APP_STORE profile 'iOS Team Store Provisioning Profile: com.myteam.myapp' to '/Users/runner/Library/MobileDevice/Provisioning Profiles/<UUID>.mobileprovision'.
Wrote IOS_APP_STORE profile 'GithubActionsMobileApp' to '/Users/runner/Library/MobileDevice/Provisioning Profiles/<UUID>.mobileprovision'.

The second profile listed is the correct profile I would like to use.

The List Certificates section returns this:

Run security find-identity -v -p codesigning
  1) <Signing ID> "Apple Distribution: My Team Name (TeamID)"
     1 valid identities found

Which is the correct signing certificate, but I still get the error.

I have tried specifying in the publish step with /p:CodeSignProvision= to specify which of the two and I get the same error.

I have tried downloading my profile, base64 encoding it and manually adding it to my keychain with the suggested code from github actions docs.

I've tried extracting the Provisioning Profile UUID and passing it directly to the publish command with -p:CodesignProvision=$PROFILE_UUID, but that also does nothing.

I have revoked the signing certificate and deleted the provisioning profile, and created new ones. My provisioning profile is a App Store Connect Distribution profile, and my certificate is a Distribution type with the name of my Team as the 'Certificate Name'. Nothing seems to have any effect.


Solution

  • I needed to directly pass the .net publish command my code sign identity and it finally could sign it: -p:CodesignKey="Apple Distribution: My Team Name (TeamID)"

    So the Publish step looks like this now:

    - name: Build iOS
            run: dotnet publish ${{ inputs.project-file }} -c ${{ inputs.build-config }} -f ${{ inputs.dotnet-version-target}}-ios -p:ArchiveOnBuild=true p:CodesignKey="Apple Distribution: My Team Name (TeamID)" --no-restore