GitHub Workflow
Contact us and we'll help you get setup, including your GitHub Workflow!
Wolfia provides a GitHub Action to use in your GitHub workflow to upload your app binaries to Wolfia.
Automatic setup
After creating an app in Wolfia, the next step will prompt to setup a GitHub workflow. This can be done automatically for you!
Once the app is created and you land on the last step to create a workflow, click Open a Pull Request.
This will open a pull request to your deploy branch in your app repository linked with GitHub. Click View Pull Request to open the pull request in GitHub.
Follow the instructions in the pull request description to add the necessary environment variables and secrets to your GitHub repository. Once complete, merge the pull request.
Return to Wolfia, we should automatically detect when it's merged, otherwise click It's merged! to force another check.
Once we are able to detect the workflow file was merged into your deploy branch, you'll see the following. This means your app is now setup to automatically upload new builds to Wolfia! Click Continue to begin releasing.
The following sections provide more details on the environment variables and workflow files if needed.
Environment variables and secrets
- Open your GitHub repository and click Settings.
- In the left sidebar, click Secrets and variables and in the dropdown select Actions.
- Note there are two tabs: Secrets (sensitive information such as API secrets) and Environment variables (nonsesntive information such as IDs). Define your secrets and environment variables here.
- First add the Wolfia variables, click on your profile picture on the top right corner, then click Settings.
- Click Generate Key.
- Copy the API Key ID into an environment variable in GitHub Settings. (
WOLFIA_API_KEY_ID
) - Copy the API Key Secret into a secret in GitHub Settings. (
WOLFIA_API_KEY_SECRET
)
Android environment variables and secrets
This section is in progress, check back soon!
iOS environment variables and secrets
If you're building an iOS app, you also need to define additional environment variables.
The first are your certificate and provisioning profile to build and sign your app. Follow GitHub documentation to install your provisioning profile on the GitHub runner. When complete, you should have the following:
- Apple signing certifcate, base64 encoded secret (
BUILD_CERTIFICATE_BASE64
) - Apple signing certifcate password secret (
P12_PASSWORD
) - Apple provisiong profile, base64 encoded secret (
BUILD_PROVISION_PROFILE_BASE64
) - Keychain password secret (
KEYCHAIN_PASSWORD
)
The remaining are necessary to upload your app to App Store Connect. Follow App Store Connect documentation to create an API key, or reference our App Store Connect documentation.
- App Store Connect API Key ID variable (
APP_CONNECT_API_KEY
) - App Store Connect API Issuer ID variable (
APP_CONNECT_API_ISSUER
) - App Store Connect API private key file, base64 encoded seceret (
APP_CONNECT_API_PRIVATE_KEY_BASE64
)
Workflow file
With the environment variables in place, you can now define a GitHub workflow.
This workflow will perform any tests you'd like (unit tests, linting, etc.), build your app, and use the wolfia-deploy
GitHub Action to upload the binary to Wolfia for release and automation.
Android workflow
Below is a sample workflow file for Android apps that should work out of the box for standard apps but may require some customization depending on how you build your app. You can copy and paste this into a file named .github/workflows/build.yml
in your repository.
name: Build and release 🚀
on:
push:
branches: [main]
jobs:
build-release:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v3
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: "adopt"
java-version: "11"
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Run Gradle
run: ./gradlew bundle --continue
- name: Sign app
uses: r0adkll/sign-android-release@v1
id: sign_app
with:
releaseDirectory: app/build/outputs/bundle/fullRelease/
signingKeyBase64: ${{ secrets.SIGNING_KEY }}
alias: ${{ secrets.ALIAS }}
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
keyPassword: ${{ secrets.KEY_PASSWORD }}
- name: Upload app to wolfia
uses: wolfia-app/wolfia-deploy@v0.0.4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
wolfia-api-key-id: ${{ vars.WOLFIA_API_KEY_ID }}
wolfia-api-key-secret: ${{ secrets.WOLFIA_API_KEY_SECRET }}
app-path: ${{steps.sign_app.outputs.signedReleaseFile}}
iOS workflow
Below is a sample workflow file for iOS apps that should work out of the box for standard apps but may require some customization depending on how you build your app. You can copy and paste this into a file named .github/workflows/build.yml
in your repository.
Replace {YOUR_APP_NAME}
with the name of your XCode app project.
name: Build and release 🚀
on:
push:
branches: [main]
jobs:
build-release:
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Install the Apple certificate and provisioning profile
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
# Create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# Import certificate and provisioning profile from secrets
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
# Create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# Import certificate to keychain
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
# Apply provisioning profile
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
- name: Show Xcode version
run: xcode-select -p
- name: Build workspace archive
run: xcodebuild -workspace "./{YOUR_APP_NAME}.xcworkspace" -scheme "{YOUR_APP_NAME}" -archivePath "./archives/archive.xcarchive" archive -destination "generic/platform=iOS"
- uses: actions/upload-artifact@v3
with:
name: archive
path: ./archives/archive.xcarchive
- name: Export archive and build IPA
run: xcodebuild -exportArchive -archivePath "./archives/archive.xcarchive" -exportPath "./output" -exportOptionsPlist ./export.plist
- uses: actions/upload-artifact@v3
with:
name: ipa
path: ./output
- name: Wolfia Deploy
uses: wolfia-app/wolfia-deploy@v0.0.4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
wolfia-api-key-id: ${{ vars.WOLFIA_API_KEY_ID }}
wolfia-api-key-secret: ${{ secrets.WOLFIA_API_KEY_SECRET }}
app-path: "./output/{YOUR_APP_NAME}.ipa"
app-store-connect-api-key-id: ${{ vars.APP_CONNECT_API_KEY }}
app-store-connect-api-issuer: ${{ vars.APP_CONNECT_API_ISSUER }}
app-store-connect-secret-base64: ${{ secrets.APP_CONNECT_API_PRIVATE_KEY_BASE64 }}
- name: Clean up (Delete keychain and provisioning profile)
if: ${{ always() }}
run: |
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
rm ~/Library/MobileDevice/Provisioning\ Profiles/build_pp.mobileprovision
iOS export PList
For the xcodebuild -exportArchive
command to work, you'll need to create an export.plist
file to configure how the project is exported. Below is a sample file that should work out of the box for standard apps.
Replace {BUNDLE_ID}
with your app's bundle ID and {PROVISIONING_PROFILE_NAME}
with the name of your provisioning profile from above (exactly as it appears).
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>app-store</string>
<key>provisioningProfiles</key>
<dict>
<key>{BUNDLE_ID}</key>
<string>{PROVISIONING_PROFILE_NAME}</string>
</dict>
<key>signingStyle</key>
<string>manual</string>
</dict>
</plist>