Skip to main content

GitHub Actions Templates

The plugin ships with two ready-to-use GitHub Actions workflow templates. Both are installed into .github/workflows/ by /deploygate:ci-setup when you choose GitHub Actions.

Required secrets

Configure these under Settings → Secrets and variables → Actions on your GitHub repository.

SecretDescription
DEPLOYGATE_API_TOKENProject API key from https://deploygate.com/organizations/{PROJECT_NAME}/settings/api_key. Use a project key rather than a personal key so CI is not tied to an individual
DEPLOYGATE_OWNER_NAMEYour DeployGate project (organization) name

For iOS builds, additionally:

SecretDescription
BUILD_CERTIFICATE_BASE64.p12 certificate (base64 encoded)
P12_PASSWORDPassword for the .p12 certificate
KEYCHAIN_PASSWORDArbitrary password used for the CI keychain
ASC_KEY_IDApp Store Connect API Key ID
ASC_ISSUER_IDApp Store Connect Issuer ID
ASC_KEY_BASE64App Store Connect API Key .p8 file (base64 encoded)

deploygate-upload.yml

Uploads the app to DeployGate on every push to the main branch.

on:
push:
branches: [main]

The template ships with both Android and iOS example steps commented out. Uncomment the section that matches your project and customize:

  • Runner: ubuntu-latest for Android, macos-latest for iOS
  • Build step: replace the placeholder echo with your actual build command
  • File path: update file_path to point to the built binary

Android uses DeployGate/deploygate-upload-github-action directly:

- name: Upload to DeployGate
uses: DeployGate/deploygate-upload-github-action@v1.1.1
with:
api_token: ${{ secrets.DEPLOYGATE_API_TOKEN }}
owner_name: ${{ secrets.DEPLOYGATE_OWNER_NAME }}
file_path: app/build/outputs/apk/debug/app-debug.apk
message: "${{ github.ref_name }} (${{ github.sha }})"
distribution_name: "Development"
release_note: "${{ github.event.head_commit.message }}"

iOS with simulator zip for Instant Device uses curl directly, because the GitHub Action does not accept an ios_simulator_zip input:

- name: Upload to DeployGate (iOS with simulator zip)
run: |
curl --fail-with-body -s -X POST \
-H "Authorization: Bearer ${{ secrets.DEPLOYGATE_API_TOKEN }}" \
-F "file=@${{ runner.temp }}/MyApp.ipa" \
-F "ios_simulator_zip=@${{ runner.temp }}/MyApp-simulator.zip" \
-F "message=${{ github.ref_name }} (${{ github.sha }})" \
-F "distribution_name=Development" \
"https://deploygate.com/api/users/${{ secrets.DEPLOYGATE_OWNER_NAME }}/apps"

The template also shows the full keychain + App Store Connect API key setup required before xcodebuild archive, and a cleanup step that deletes the keychain on completion.

deploygate-pr.yml

Creates a distribution page per pull request, updates it on every push, and deletes it on close.

on:
pull_request:
types: [opened, synchronize, closed]

permissions:
contents: read
pull-requests: write
deployments: write

Behavior:

  1. On opened / synchronize — build the app and upload. The first upload creates a new distribution page titled PR #<N>: <PR title>; subsequent uploads reuse the same page by reading the distribution's access_key from a hidden marker (<!-- deploygate:access_key=... -->) embedded in a PR comment, and passing it back as the distribution_key form parameter on upload.
  2. Comment — posts or updates a PR comment containing the distribution URL and a QR code (generated via https://deploygate.com/qr). PCs can preview via Instant Device; phones install directly.
  3. Title sync — if the PR title changes between pushes, the distribution page title is updated to match, preserving active and release_scope from the current state.
  4. GitHub Deployment — creates a deployment in the deploygate environment with the distribution URL, so the environment appears in the PR's timeline.
  5. On closedDELETE /api/distributions/{access_key} removes the distribution page. Uploaded binaries are preserved.

The upload step uses curl rather than the GitHub Action so it can handle the optional ios_simulator_zip attachment:

- name: Upload to DeployGate
id: upload
shell: bash
run: |
ARGS=(--fail-with-body -s -X POST \
-H "Authorization: Bearer ${{ secrets.DEPLOYGATE_API_TOKEN }}" \
-F "file=@${{ runner.temp }}/MyApp.ipa" \
-F "message=PR #${{ github.event.pull_request.number }} (${{ github.sha }})" \
-F "release_note=${{ github.event.pull_request.title }}")

if [ -f "${{ runner.temp }}/MyApp-simulator.zip" ]; then
ARGS+=(-F "ios_simulator_zip=@${{ runner.temp }}/MyApp-simulator.zip")
fi

DIST_KEY="${{ steps.find-key.outputs.distribution_key }}"
if [ -n "$DIST_KEY" ]; then
ARGS+=(-F "distribution_key=$DIST_KEY")
else
ARGS+=(-F "distribution_name=PR #${{ github.event.pull_request.number }}: ${{ github.event.pull_request.title }}")
fi

RESPONSE=$(curl "${ARGS[@]}" \
"https://deploygate.com/api/users/${{ secrets.DEPLOYGATE_OWNER_NAME }}/apps")

For Android projects that do not need ios_simulator_zip, the template shows a commented-out alternative using DeployGate/deploygate-upload-github-action directly, which is simpler but does not support the simulator zip input.

Customization checklist

After /deploygate:ci-setup installs the templates, check these before merging:

  • Repository secrets configured (see table above)
  • Runner changed to macos-latest for iOS builds
  • Build step replaced with your actual build commands
  • file_path points to the correct built binary
  • For iOS: -scheme, DEVELOPMENT_TEAM, and any Matchfile / fastlane configuration aligned with the existing project
  • Branch name in push.branches matches your default branch (main by default)