bscotch / igor-setup

A GitHub Action to set up Igor to allow Building via Command Line for GameMaker projects.
MIT License
4 stars 3 forks source link

Android build asks me for a licence.plist file #4

Open BrunoDG opened 2 months ago

BrunoDG commented 2 months ago

Hey guys, I've been following a tutorial on https://gamemaker.io/en/blog/bs-tech-automate-builds to create automatic builds on Android, that should be working. But when I try to run, the following message pops up on my igor-setup workflow's step:

Error

Run bscotch/igor-setup@v1
Inferring runtime from target-yyp: /home/runner/work/build-test/build-test/Survivor Game - Build Test.yyp
Using local settings file: /home/runner/work/build-test/build-test/local_settings.json
Release build
System.Net.WebException: The remote server returned an error: (404) Not Found.
   at System.Net.HttpWebRequest.GetResponse()
   at System.Net.WebClient.GetWebResponse(WebRequest request)
   at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream)
   at System.Net.WebClient.UploadBits(WebRequest request, Stream readStream, Byte[] buffer, Int32 chunkSize, Byte[] header, Byte[] footer)
   at System.Net.WebClient.UploadDataInternal(Uri address, String method, Byte[] data, WebRequest& request)
   at System.Net.WebClient.UploadString(Uri address, String method, String data)
   at System.Net.WebClient.UploadString(String address, String method, String data)
   at Igor.RuntimeBuilder.FetchLicense()
Igor complete.
Error: ENOENT: no such file or directory, open '/home/runner/work/_actions/bscotch/igor-setup/v1/dist/gm-sandbox/gm-user/tempUser/licence.plist'

I tried looking at other places like forums and such, but no one seems to have that issue.

How to reproduce the following error

Use the following job:

  build-android:
    runs-on: ubuntu-latest
    steps:
      # Check out the repository with the GameMaker project
      - uses: actions/checkout@v4
        with:
          lfs: true
      # This step finds the yyp file in the repository and saves the path to an output
      - id: find_yyp
        name: Find the yyp file
        run: |
          yyp=$(find ${{ github.workspace }} -name "*.yyp")
          echo "YYP file found at: $yyp"
          echo "yyp-path=$yyp" >> $GITHUB_OUTPUT
      #region Android setup
      - name: Create the keystore file from secrets
        id: write_file
        uses: timheuer/base64-to-file@v1.2
        with:
          fileName: 'myTemporaryFile.keystore'
          encodedString: ${{ secrets.KEYSTORE }}
      - name: Create the local-settings-override-file for igor-setup
        run: |
          echo '{
          "machine.Platform Settings.Android.Keystore.filename": "${{ steps.write_file.outputs.filePath }}", 
          "machine.Platform Settings.Android.Keystore.keystore_password": "${{ secrets.SIGNING_KEY_PASSWORD }}", 
          "machine.Platform Settings.Android.Keystore.keystore_alias_password": "${{ secrets.SIGNING_STORE_PASSWORD }}", 
          "machine.Platform Settings.Android.Keystore.alias": "${{ secrets.SIGNING_KEY_ALIAS }}"
          }' \
          > local_settings.json
      - name: Set up ffmpeg # This step may be removed when https://github.com/YoYoGames/GameMaker-Bugs/issues/4977 is fixed
        uses: FedericoCarboni/setup-ffmpeg@v3
        with:
          ffmpeg-version: '6.1.0'
      - name: Set Up Android SDK platform-tools # The default Android SDK does not include platform-tools and its component `adb`, which is required by Igor for the Android build
        run: |
          ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager \
          --sdk_root=$ANDROID_SDK_ROOT \
          "platform-tools"
      #endregion
      # This step sets up the GameMaker build CLI tool Igor https://github.com/bscotch/igor-setup
      - name: use Igor Setup
        uses: bscotch/igor-setup@v1
        id: igor
        with:
          local-settings-override-file: ${{ github.workspace }}/local_settings.json
          target-yyp: ${{ steps.find_yyp.outputs.yyp-path }}
          access-key: ${{ secrets.GSA_ACCESS_KEY }} 

      # This step uses Igor to build the GameMaker project https://github.com/bscotch/igor-build
      - name: use Igor build
        uses: bscotch/igor-build@v1
        id: build
        with:
          yyp-path: ${{ steps.find_yyp.outputs.yyp-path }}
          user-dir: ${{ steps.igor.outputs.user-dir }}
      - name: upload build as artifact
        uses: actions/upload-artifact@v4
        with:
          name: android-build-${{ needs.define-vars.outputs.VRS }}.zip
          path: ${{ steps.build.outputs.out-dir }}
          retention-days: 1

At use Igor Setup step, it gives the licence.plist error. But there's no definition to create that file or folder. Although on a Windows instance it runs properly. Is there a bug with the Ubuntu folder?

shichen85 commented 2 months ago

The 404 error indicates that when running igor runtime FetchLicense, Igor could not fetch the license from GameMaker's server. It could mean that your access key does not have license to the Android export or the Ubuntu Igor. If you have a Ubuntu machine, you can try running igor runtime FetchLicense there with your access key to see if it can successfully generate the license file. If not, you will want to sort that out with the GameMaker customer support.

For igor runtime FetchLicense, see https://manual.gamemaker.io/monthly/en/#t=Settings%2FBuilding_via_Command_Line.htm

BrunoDG commented 2 months ago

I think I solved this issue. Just redid the workflow and it worked well. Didn't understand yet what happened, but ok.

Now, I'm with another issue, but I don't know if it's correct to include it in here or if should I open another issue as question:

I've included the Temurin JDK as version 21, but it keeps telling me that my build.gradle is at version 11. The problem is that, I've included the new JAVA_HOME variable to redirect to version 21, although it keeps telling me that the version hasn't changed. How can I change the build.gradle file since it's not included on my gamemaker config?

shichen85 commented 2 months ago

I think I solved this issue. Just redid the workflow and it worked well. Didn't understand yet what happened, but ok.

Now, I'm with another issue, but I don't know if it's correct to include it in here or if should I open another issue as question:

I've included the Temurin JDK as version 21, but it keeps telling me that my build.gradle is at version 11. The problem is that, I've included the new JAVA_HOME variable to redirect to version 21, although it keeps telling me that the version hasn't changed. How can I change the build.gradle file since it's not included on my gamemaker config?

  1. Are you using a self-hosted runner or the GitHub hosted runner?
  2. GameMaker reads the JDK location from /home/runner/work/build-test/build-test/local_settings.json's machine.Platform Settings.Android.Paths.jdk_location key, which you can set in your Create the local-settings-override-file for igor-setup step. I don't see you setting that in your setup, so that might be the problem. If you don't set that, GameMaker will use the default value defined in "runtimes\runtime-2024.1000.0.648\bin\platform_setting_defaults.json"
BrunoDG commented 1 month ago

Worked properly, thanks.

Another question is: Do I need to reference the Keystore base64 inside the local_settings, so it can change the default one for my new one? This is kinda weird, because the key my client gave me generated properly, but neither mine nor the client key are working on my action.

shichen85 commented 1 month ago

Worked properly, thanks.

Another question is: Do I need to reference the Keystore base64 inside the local_settings, so it can change the default one for my new one? This is kinda weird, because the key my client gave me generated properly, but neither mine nor the client key are working on my action.

GameMaker encrypts the value of "machine.Platform Settings.Android.Keystore.keystore_password" and "machine.Platform Settings.Android.Keystore.keystore_alias_password" based on the GameMaker account that is signed-in to the IDE. You can see this behavior when you sign in to the GameMaker IDE with two different accounts and set up the Android Platform preferences with the same keystore credentials. When you open the local_settings.json files of both accounts, the alue of "machine.Platform Settings.Android.Keystore.keystore_password" and "machine.Platform Settings.Android.Keystore.keystore_alias_password" will appear different.

What this means is that:

  1. You should make sure you are using the same GameMaker account to generate the Igor access-key and sign in to your GameMaker IDE
  2. Configure the Keystore File, its alias, and password as mentioned in the GameMaker guide Setting Up for Android.
  3. Locate the local_settings.json file, which stores your IDE preferences and the Android SDK configuration. Copy the entries "machine.Platform Settings.Android.Keystore.keystore_password" and "machine.Platform Settings.Android.Keystore.alias"'s values and store them as GitHub secrets.
BrunoDG commented 1 month ago

GameMaker encrypts the value of "machine.Platform Settings.Android.Keystore.keystore_password" and "machine.Platform Settings.Android.Keystore.keystore_alias_password" based on the GameMaker account that is signed-in to the IDE. You can see this behavior when you sign in to the GameMaker IDE with two different accounts and set up the Android Platform preferences with the same keystore credentials. When you open the local_settings.json files of both accounts, the alue of "machine.Platform Settings.Android.Keystore.keystore_password" and "machine.Platform Settings.Android.Keystore.keystore_alias_password" will appear different.

What this means is that:

  1. You should make sure you are using the same GameMaker account to generate the Igor access-key and sign in to your GameMaker IDE
  2. Configure the Keystore File, its alias, and password as mentioned in the GameMaker guide Setting Up for Android.
  3. Locate the local_settings.json file, which stores your IDE preferences and the Android SDK configuration. Copy the entries "machine.Platform Settings.Android.Keystore.keystore_password" and "machine.Platform Settings.Android.Keystore.alias"'s values and store them as GitHub secrets.

I tried doing it, I was using my username and password before, but it wasn't logging in. This time, I tried sing the same user that is at GH Actions' account to run the setup and build. but keeps giving me the same error as before:

AndroidEnvironment Manifest Permissions Manifest Attributes Manifest Metadata Check GML functions Licensing System.FormatException: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters. at System.Convert.FromBase64CharPtr(Char* inputPtr, Int32 inputLength) at System.Convert.FromBase64String(String s) at Igor.Utils.FromBase64(String _message) at Igor.Utils.Decrypt(String _encryptedString, String _key) at Igor.AndroidUtils.GetKeystorePassword(String _target) at Igor.AndroidBuilder.CreateTargetExe() at Igor.AndroidBuilder.Package() at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor) at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

When I remove the references to the Username and Alias for the account, it proceeds with the building process properly, until it hits this error after starting the gradle.build process:

FAILURE: Build failed with an exception. * Where: Build file '/home/runner/work/_actions/bscotch/igor-setup/v1/dist/gm-sandbox/gm-cache/android/Default/com.creativehand.tinywitch/build.gradle' line: 29 * What went wrong: A problem occurred evaluating project ':com.creativehand.tinywitch'. > path may not be null or empty string. path=''

Since there's nowhere to include said path on anywhere, nor the instructions and I don't have access to the gradle.build file of this project, I'm just responsible for creating the workflow itself, I can't seem to find where should I include said path. I'm starting to feel lost.

shichen85 commented 1 month ago

Worked properly, thanks.

Another question is: Do I need to reference the Keystore base64 inside the local_settings, so it can change the default one for my new one? This is kinda weird, because the key my client gave me generated properly, but neither mine nor the client key are working on my action.

Let's walk this back a little bit to make sure I understand your situation. When you say "refercen the Kystore base64 inside the local_settings", what do you mean?

BrunoDG commented 1 month ago

Worked properly, thanks. Another question is: Do I need to reference the Keystore base64 inside the local_settings, so it can change the default one for my new one? This is kinda weird, because the key my client gave me generated properly, but neither mine nor the client key are working on my action.

Let's walk this back a little bit to make sure I understand your situation. When you say "refercen the Kystore base64 inside the local_settings", what do you mean?

When I said "Reference the Keystore_base64 inside the local_settings", I meant converting the keystore file to a base64 string and using it as my keystore file, included the local_settings file. But the problem is: either while I'm using my keystore file or my client's keystore file, it keeps giving me the same error, as it is not a valid base64 file.

shichen85 commented 1 month ago

I see. If you look at the error stack you got, it mentioned:

at Igor.AndroidUtils.GetKeystorePassword(String _target)

So it is saying that "machine.Platform Settings.Android.Keystore.keystore_password": "${{ secrets.SIGNING_KEY_PASSWORD }}", is not a valid Base-64 string. Can you confirm that you copied the value from your local_settings.json file at %AppData%\GameMakerStudio2\<your_account_name>\ or ~/Library/Application Support/GameMakerStudio2/<your_account_name>/?

BrunoDG commented 1 month ago

Ok, it did work. It was just because I was including the entire password, but not converting it as a base64 string. Weird, because it wasn't telling me to do so in the GameMaker guide Setting Up for Android.

Anyways, it worked at last. Also, it now gave me another error, that's telling me that "> path may not be null or empty string. path='' ". But where do I include that path variable? I don't see it anywhere to include that on my actions.

shichen85 commented 1 month ago

Ok, it did work. It was just because I was including the entire password, but not converting it as a base64 string. Weird, because it wasn't telling me to do so in the GameMaker guide Setting Up for Android.

Anyways, it worked at last. Also, it now gave me another error, that's telling me that "> path may not be null or empty string. path='' ". But where do I include that path variable? I don't see it anywhere to include that on my actions.

I think that error is suggesting that it could not find the java keystore file, as this stackoverflow thread showed. Can you post your updated workflow file here?

BrunoDG commented 1 month ago

Ok, it did work. It was just because I was including the entire password, but not converting it as a base64 string. Weird, because it wasn't telling me to do so in the GameMaker guide Setting Up for Android. Anyways, it worked at last. Also, it now gave me another error, that's telling me that "> path may not be null or empty string. path='' ". But where do I include that path variable? I don't see it anywhere to include that on my actions.

I think that error is suggesting that it could not find the java keystore file, as this stackoverflow thread showed. Can you post your updated workflow file here?

Of course! Here it is:

name: Continuous Integration for Android Export
# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the "master" branch
  push:
    branches: [ "master" ]
  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:
  # This line allows you to run the workflow from another workflow
  # workflow_call: 

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  define-vars:
    runs-on: windows-latest

    steps:
      - uses: actions/checkout@v4
        with:
          lfs: true

    # Reads JSON file and converts to ENV variables
      - id: read_json
        name: Reads JSON
        uses: GuillaumeFalourd/convert-json-to-env@v1
        with:
          json_file: ./metadata.json

  build-mobile:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest
    needs: define-vars

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v4
        with:
          lfs: true

      # This step finds the yyp file in the repository and saves the path to an output
      - id: find_yyp
        name: Find the yyp file
        run: |
          yyp=$(find ${{ github.workspace }} -name "*.yyp")
          echo "YYP file found at: $yyp"
          echo "yyp-path=$yyp" >> $GITHUB_OUTPUT

      #region Android setup
      #- name: Create the keystore file from secrets
      #  id: write_file
      #  uses: timheuer/base64-to-file@v1.2
      #  with:
      #    fileName: 'myTemporaryFile.keystore'
      #    encodedString: ${{ secrets.KEYSTORE_BASE64 }}

      - name: Configuring Java version 21
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin' # See 'Supported distributions' for available options
          java-version: '21'

      - name: Create the local-settings-override-file for igor-setup
       "machine.Platform Settings.Android.Keystore.filename": "${{ steps.write_file.outputs.filePath }}", 
       "machine.Platform Settings.Android.Keystore.keystore_password": "${{ secrets.KEYSTORE_PASSWORD }}", 
       "machine.Platform Settings.Android.Keystore.keystore_alias_password": "${{ secrets.KEYSTORE_PASSWORD }}", 
       "machine.Platform Settings.Android.Keystore.alias": "${{ secrets.KEYSTORE_USERNAME }}",
       # Those four lines were commented before, now they do work.
        run: |
          echo '{
          "machine.Platform Settings.Android.Paths.jdk_location": "${{ env.JAVA_HOME }}"
          }' \
          > local_settings.json

      - name: Set up ffmpeg # This step may be removed when https://github.com/YoYoGames/GameMaker-Bugs/issues/4977 is fixed
        uses: FedericoCarboni/setup-ffmpeg@v3
        with:
          ffmpeg-version: '6.1.0'

      - name: Set Up Android SDK platform-tools # The default Android SDK does not include platform-tools and its component `adb`, which is required by Igor for the Android build
        run: |
          ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager \
          --sdk_root=$ANDROID_SDK_ROOT \
          "platform-tools"
      #endregion

      # This step sets up the GameMaker build CLI tool Igor https://github.com/bscotch/igor-setup
      - name: use Igor Setup
        uses: bscotch/igor-setup@v1
        id: igor
        with:
          local-settings-override-file: ${{ github.workspace }}/local_settings.json
          target-yyp: ${{ steps.find_yyp.outputs.yyp-path }}
          access-key: ${{ secrets.ACCESS_KEY }}

      # This step uses Igor to build the GameMaker project https://github.com/bscotch/igor-build
      - name: use Igor build
        uses: bscotch/igor-build@v1
        id: build
        with:
          yyp-path: ${{ steps.find_yyp.outputs.yyp-path }}
          user-dir: ${{ steps.igor.outputs.user-dir }}

      # This step uploads the build to the artifacts, so you can download it from the GitHub Actions 
      # page or use it in another workflow
      - name: upload-build
        uses: actions/upload-artifact@v4
        with:
          name: android-build-${{ github.env.version }} # Built game name, change for your game.
          path: ${{ steps.build.outputs.out-dir }}
          retention-days: 1 
          # Longer retention days can incur additional charges. 
          # See https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts

This was my mistake, as the keystore and password files are commented. Now I've just uncommented them, tested at my workflow and I think it works properly. I have to retry though, since it's a password issue now. It tells me that my password is wrong for my key. Now I think I can handle the error. I'll post the update here when it works! :)

BrunoDG commented 3 weeks ago

Is it normal that, even when including the correct password under the base64 import of the same project, it keeps telling me that the password for the keystore file is incorrect?

shichen85 commented 2 weeks ago

Is it normal that, even when including the correct password under the base64 import of the same project, it keeps telling me that the password for the keystore file is incorrect?

Not normal in my experience. If you want to share the whole log with the error message, we might have a better idea of what's going on.