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.
| Secret | Description |
|---|---|
DEPLOYGATE_API_TOKEN | Project 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_NAME | Your DeployGate project (organization) name |
For iOS builds, additionally:
| Secret | Description |
|---|---|
BUILD_CERTIFICATE_BASE64 | .p12 certificate (base64 encoded) |
P12_PASSWORD | Password for the .p12 certificate |
KEYCHAIN_PASSWORD | Arbitrary password used for the CI keychain |
ASC_KEY_ID | App Store Connect API Key ID |
ASC_ISSUER_ID | App Store Connect Issuer ID |
ASC_KEY_BASE64 | App 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-latestfor Android,macos-latestfor iOS - Build step: replace the placeholder
echowith your actual build command - File path: update
file_pathto 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:
- On
opened/synchronize— build the app and upload. The first upload creates a new distribution page titledPR #<N>: <PR title>; subsequent uploads reuse the same page by reading the distribution'saccess_keyfrom a hidden marker (<!-- deploygate:access_key=... -->) embedded in a PR comment, and passing it back as thedistribution_keyform parameter on upload. - 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. - Title sync — if the PR title changes between pushes, the distribution page title is updated to match, preserving
activeandrelease_scopefrom the current state. - GitHub Deployment — creates a deployment in the
deploygateenvironment with the distribution URL, so the environment appears in the PR's timeline. - On
closed—DELETE /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-latestfor iOS builds - Build step replaced with your actual build commands
-
file_pathpoints to the correct built binary - For iOS:
-scheme,DEVELOPMENT_TEAM, and anyMatchfile/ fastlane configuration aligned with the existing project - Branch name in
push.branchesmatches your default branch (mainby default)
Related
/deploygate:ci-setup— the skill that installs these templates- DeployGate Upload GitHub Action — the underlying action used by the Android examples