Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Do actual build uploads
Browse files Browse the repository at this point in the history
luxaritas committed Sep 6, 2024
1 parent dfc756e commit b68a9dd
Showing 6 changed files with 300 additions and 0 deletions.
151 changes: 151 additions & 0 deletions .github/workflows/google-play/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .github/workflows/google-play/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "module",
"dependencies": {
"jsonwebtoken": "^9.0.2"
}
}
20 changes: 20 additions & 0 deletions .github/workflows/google-play/src/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// @ts-check

export function parseArgs() {
const args = process.argv.slice(2);
const mode = args.shift();
if (!mode) throw new Error('Missing arguments');

if (mode === 'upload') {
if (args.length < 2) throw new Error('Missing arguments');
const [apiKey, bundlePath] = args;
return {
/** @type {'upload'} */
mode: 'upload',
apiKey: JSON.parse(Buffer.from(apiKey, 'base64').toString()),
bundlePath
};
} else {
throw new Error('Invalid mode')
}
}
13 changes: 13 additions & 0 deletions .github/workflows/google-play/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// @ts-check
import { parseArgs } from "./cli.js";
import { PlayStoreApi } from "./play-store-api.js";

const PACKAGE_NAME = 'org.eternagame.mob';

const args = parseArgs();
const playStoreApi = await PlayStoreApi.create(args.apiKey);
if (args.mode === 'upload') {
const editId = await playStoreApi.insertEdit(PACKAGE_NAME);
await playStoreApi.uploadBundle(PACKAGE_NAME, editId, args.bundlePath);
await playStoreApi.commitEdit(PACKAGE_NAME, editId);
}
91 changes: 91 additions & 0 deletions .github/workflows/google-play/src/play-store-api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// @ts-check
import { readFile } from 'fs/promises';
import jwt from 'jsonwebtoken';

export class PlayStoreApi {
/**
* @param {string} accessToken
* @access private
*/
constructor(accessToken) {
this.accessToken = accessToken;
}

/**
* @param {{
* type: string;
* project_id: string;
* private_key_id: string;
* private_key: string;
* client_email: string;
* client_id: string;
* auth_uri: string;
* token_uri: string;
* auth_provider_x509_cert_url: string;
* client_x509_cert_url: string;
* universe_domain: string;
* }} apiKey
*/
static async create(apiKey) {
const authToken = jwt.sign({
scope: 'https://www.googleapis.com/auth/androidpublisher'
}, apiKey['private_key'], {
algorithm: 'RS256',
keyid: apiKey['private_key_id'],
issuer: apiKey['client_email'],
audience: apiKey['token_uri'],
expiresIn: '5m',
});
const res = await fetch(apiKey['token_uri'], {
method: 'POST',
body: new URLSearchParams({
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion: authToken
}).toString()
});
const parsed = await res.json();
return new PlayStoreApi(parsed['access_token']);
}

/**
* @param {string} packageName
* @returns {Promise<string>} edit ID
*/
async insertEdit(packageName) {
const res = await fetch(`https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${packageName}/edits`, {
method: 'POST',
headers: {
Authorization: `Bearer ${this.accessToken}`
}
});
const parsed = await res.json();
return parsed['id'];
}

/**
* @param {string} packageName
* @param {string} editId
* @param {string} bundlePath
*/
async uploadBundle(packageName, editId, bundlePath) {
const bundle = await readFile(bundlePath);
await fetch(`https://androidpublisher.googleapis.com/upload/androidpublisher/v3/applications/${packageName}/edits/${editId}/bundles?uploadType=media`, {
method: 'POST',
headers: {
Authorization: `Bearer ${this.accessToken}`,
'Content-Type': 'application/octet-stream',
'Content-Length': bundle.length.toString(),
},
body: bundle
});
}

async commitEdit(packageName, editId) {
await fetch(`https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${packageName}/edits/${editId}:commit`, {
method: 'POST',
headers: {
Authorization: `Bearer ${this.accessToken}`,
},
});
}
}
19 changes: 19 additions & 0 deletions .github/workflows/upload-build.yml
Original file line number Diff line number Diff line change
@@ -23,15 +23,34 @@ jobs:
run-id: ${{ inputs.run-id }}
- name: Decrypt build
run: gpg --decrypt --output=./Eterna.ipa --passphrase ${{ secrets.ARTIFACT_ENCRYPTION_KEY }} --batch release-ios
- name: Set up App Store Connect API key
env:
APP_STORE_CONNECT_API_KEY_BASE64: ${{ secrets.APP_STORE_CONNECT_API_KEY_BASE64 }}
run: echo $APP_STORE_CONNECT_API_KEY_BASE64 | base64 --decode > "$RUNNER_TEMP/AuthKey_${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}.p8"
#- name: Upload to App Store
# run: API_PRIVATE_KEYS_DIR=$RUNNER_TEMP xcrun altool --upload-package Eterna.ipa --type ios --apiIssuer ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }} --apiKey ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}

upload-android:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
with:
ref: ci
submodules: false
persist-credentials: false
sparse-checkout: .github/**/*
sparse-checkout-cone-mode: false
- uses: actions/download-artifact@v4
with:
name: release-android
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ inputs.run-id }}
- name: Decrypt build
run: gpg --decrypt --output=./app-release.aab --passphrase ${{ secrets.ARTIFACT_ENCRYPTION_KEY }} --batch release-android
- name: Install dependencies for upload script
run: npm ci
working-directory: ./.github/workflows/google-play
- run: ls .github/workflows/google-play
#- name: Upload to Google Play
# run: node ./.github/workflows/google-play

0 comments on commit b68a9dd

Please sign in to comment.