unity-builder icon indicating copy to clipboard operation
unity-builder copied to clipboard

Github Secret cannot store androidKeystoreBase64, the keystore file is too large. How do I pass keystore to the builder?

Open jacattrongnlh opened this issue 3 years ago • 3 comments

In the documentation https://game.ci/docs/github/builder#androidkeystorebase64, it's wrote:

It is recommended to use GitHub Secrets.

However, my keystore file is really big (50KB), so when it's encoded to base64, it's >40000 characters, which Github secret refuse to accept.

So my developer wrote the yml file so that it will download the keystore file from a link, and then encode that file and pass it to the game-ci's build step.

But doing this leads to error:

UnityException: Can not sign the application Unable to sign the application; please provide passwords!

How do I pass the keystore correctly? What am I doing wrong?

My env:

env:
  AWS_ENDPOINT_CDN: ${{ secrets.AWS_ENDPOINT_CDN }}
  UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
  UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
  UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
  PROJECT_PATH: .
  ANDROID_APP_BUNDLE: true
  DISCORD_WEBHOOK : ${{ secrets.DISCORD_WEBHOOK }}
  REPO_NAME: ${{ github.event.repository.name }}
  REPO_URL: ${{ github.event.repository.url }}
  BRANCH_NAME: ${{ github.ref_name }}
  USER_URL: ${{ github.event.sender.html_url }}
  COMMIT_MESSAGE: ${{ github.event.commits[0].message }}
  COMMIT_HASH: ${{ github.event.head_commit.id }}
  COMMIT_URL: ${{ github.event.head_commit.url }}
  COMMIT_USER: ${{ github.event.sender.login }}
  COMMIT_TIME: ${{ github.event.head_commit.timestamp }}
  COMMIT_COMPARE: ${{ github.event.compare }}
  USER_AVATAR: ${{ github.event.sender.avatar_url }}
  ORG_AVATAR: ${{ github.event.organization.avatar_url }}
  ORG_URL: ${{ github.event.organization.url }}
  ORG_NAME: ${{ github.event.organization.login }}
  ANDROID_KEYSTORE_LINK: ${{ secrets.ANDROID_KEYSTORE_LINK }}

game builder step:

      - name: Code repo check out 📁
        uses: actions/checkout@v3
        with:
          lfs: true
          submodules: true

      - name: Cache ✨
        uses: actions/cache@v3
        with:
          path: ./Library
          key: Library-${{ env.REPO_NAME }}-iOS
          restore-keys: |
            Library-${{ env.REPO_NAME }}-
            Library-

      - name: Get keystore 🔐
        id: keystore
        run: |
          echo "::set-output name=keystore_data64::$(wget ${{ env.ANDROID_KEYSTORE_LINK }} -q -O - | base64)"

      - name: Game builder 🌀
        uses: game-ci/unity-builder@v2
        with:
          allowDirtyBuild: true
          projectPath: ${{ env.PROJECT_PATH }}
          targetPlatform: Android
          androidAppBundle: true
          androidKeystoreName: ${{ secrets.ANDROID_KEYSTORE_NAME }}
          androidKeystoreBase64: ${{ steps.keystore.outputs.keystore_data64 }}
          androidKeystorePass: ${{ secrets.ANDROID_KEYSTORE_PASS }}
          androidKeyaliasName: ${{ secrets.ANDROID_KEYALIAS_NAME }}
          androidKeyaliasPass: ${{ secrets.ANDROID_KEYALIAS_PASS }}

jacattrongnlh avatar Oct 07 '22 03:10 jacattrongnlh

In my secrets, I don't know what value to set ANDROID_KEYSTORE_NAME to, so I leave it blank. Is that why it does not work?

jacattrongnlh avatar Oct 07 '22 03:10 jacattrongnlh

My advice would be to start following best practices. It would make the process a lot smoother.

  1. Android keystore being too largs:

Let's imagine that 50KB is roughly 45.000 characters. A lot of these will be used for encoding and making the structure of the android key store. However, if you use 20 APIs, each with a key of 64 characters that would still roughly only be 1KB.

The Android Keystore system lets you store cryptographic keys in a container to make it more difficult to extract from the device. Once keys are in the keystore, they can be used for cryptographic operations with the key material remaining non-exportable.

Make sure you only store cryptographic keys, not all your settings or whatnot. Same goes for GitHub Secrets; only put secrets in there, not configuration options.

  1. Security first:

It is not encouraged to create a global env in your workflow and put secrets in there, because any job could then access all that data.

  1. Follow our documentation (more closely):

Our documentation clearly states a name for your android keystore is required. Trying without it will only waste time and effort.

webbertakken avatar Oct 07 '22 12:10 webbertakken

Make sure you only store cryptographic keys, not all your settings or whatnot. Same goes for GitHub Secrets; only put secrets in there, not configuration options.

Could you elaborate? I don't know how to do that, I use Unity's Keystore manager to generate keystore and alias. And this keystore containing about 20 aliases is being used to sign released apps on our Google Play Store.

It is not encouraged to create a global env in your workflow and put secrets in there, because any job could then access all that data.

How should I store the secret? A secret for each repo?

jacattrongnlh avatar Oct 10 '22 03:10 jacattrongnlh