From f3ea57132d687888a31247c1cbcf0122da194ced Mon Sep 17 00:00:00 2001 From: konoart Date: Tue, 23 Jul 2024 15:19:14 +0200 Subject: [PATCH] Add initial alpha testing support --- example/config.yaml | 1 + packages/cli/src/CliSetup.ts | 7 +++++ .../src/commands/publish/PublishCliSubmit.ts | 3 +++ .../src/commands/publish/PublishCliUpdate.ts | 3 +++ packages/cli/src/config/PublishDetails.ts | 12 +++++++++ .../prebuild_schema/publishing_source.yaml | 3 ++- .../core/src/publish/PublishCoreSubmit.ts | 27 +++++++++++++++++-- .../core/src/publish/PublishCoreUpdate.ts | 27 +++++++++++++++++-- .../core/src/publish/dapp_publisher_portal.ts | 2 ++ packages/core/src/types.ts | 1 + 10 files changed, 81 insertions(+), 5 deletions(-) diff --git a/example/config.yaml b/example/config.yaml index ac1345f..4a78f24 100644 --- a/example/config.yaml +++ b/example/config.yaml @@ -52,3 +52,4 @@ release: solana_mobile_dapp_publisher_portal: google_store_package: com.solanamobile.cutekitten.gps testing_instructions: Here are some steps informing Solana Mobile of how to test this dapp. You can specify multiple lines of instructions. For example, if a login is needed, you would add those details here. + #alpha_testers: 3tgkMfug2gs82sy2wexQjMkR12JzFcX9rSLd9yM9m38g,G65S4B3RkFpPAt9CwY4cZXptNSkTS6c8hFW1m89GCuB1 -- specify your own diff --git a/packages/cli/src/CliSetup.ts b/packages/cli/src/CliSetup.ts index 7080923..7abf7f0 100644 --- a/packages/cli/src/CliSetup.ts +++ b/packages/cli/src/CliSetup.ts @@ -303,6 +303,7 @@ publishCommand "-d, --dry-run", "Flag for dry run. Doesn't submit the request to the publisher portal." ) + .option("-l, --alpha", "Flag to mark the submission as alpha test.") .action( async ({ appMintAddress, @@ -312,6 +313,7 @@ publishCommand compliesWithSolanaDappStorePolicies, requestorIsAuthorized, dryRun, + alpha, }) => { await tryWithErrorMessage(async () => { await checkForSelfUpdate(); @@ -335,6 +337,7 @@ publishCommand compliesWithSolanaDappStorePolicies: compliesWithSolanaDappStorePolicies, requestorIsAuthorized: requestorIsAuthorized, critical: false, + alphaTest: alpha, }); } else { await publishSubmitCommand({ @@ -345,6 +348,7 @@ publishCommand dryRun: dryRun, compliesWithSolanaDappStorePolicies: compliesWithSolanaDappStorePolicies, requestorIsAuthorized: requestorIsAuthorized, + alphaTest: alpha, }); } @@ -389,6 +393,7 @@ publishCommand "-d, --dry-run", "Flag for dry run. Doesn't submit the request to the publisher portal." ) + .option("-l, --alpha", "Flag to mark the submission as alpha test.") .action( async ({ appMintAddress, @@ -399,6 +404,7 @@ publishCommand requestorIsAuthorized, critical, dryRun, + alpha, }) => { await tryWithErrorMessage(async () => { await checkForSelfUpdate(); @@ -421,6 +427,7 @@ publishCommand compliesWithSolanaDappStorePolicies, requestorIsAuthorized, critical, + alphaTest: alpha, }); if (dryRun) { diff --git a/packages/cli/src/commands/publish/PublishCliSubmit.ts b/packages/cli/src/commands/publish/PublishCliSubmit.ts index f2d7eb3..11e3e74 100644 --- a/packages/cli/src/commands/publish/PublishCliSubmit.ts +++ b/packages/cli/src/commands/publish/PublishCliSubmit.ts @@ -14,6 +14,7 @@ type PublishSubmitCommandInput = { dryRun: boolean; compliesWithSolanaDappStorePolicies: boolean; requestorIsAuthorized: boolean; + alphaTest?: boolean; }; export const publishSubmitCommand = async ({ @@ -24,6 +25,7 @@ export const publishSubmitCommand = async ({ dryRun = false, compliesWithSolanaDappStorePolicies = false, requestorIsAuthorized = false, + alphaTest }: PublishSubmitCommandInput) => { showMessage( `Publishing Estimates`, @@ -74,6 +76,7 @@ export const publishSubmitCommand = async ({ solanaMobileDappPublisherPortalDetails, compliesWithSolanaDappStorePolicies, requestorIsAuthorized, + alphaTest, }, dryRun ); diff --git a/packages/cli/src/commands/publish/PublishCliUpdate.ts b/packages/cli/src/commands/publish/PublishCliUpdate.ts index d70d619..3bd8713 100644 --- a/packages/cli/src/commands/publish/PublishCliUpdate.ts +++ b/packages/cli/src/commands/publish/PublishCliUpdate.ts @@ -14,6 +14,7 @@ type PublishUpdateCommandInput = { compliesWithSolanaDappStorePolicies: boolean; requestorIsAuthorized: boolean; critical: boolean; + alphaTest?: boolean; }; export const publishUpdateCommand = async ({ @@ -25,6 +26,7 @@ export const publishUpdateCommand = async ({ compliesWithSolanaDappStorePolicies = false, requestorIsAuthorized = false, critical = false, + alphaTest, }: PublishUpdateCommandInput) => { showMessage( @@ -83,6 +85,7 @@ export const publishUpdateCommand = async ({ compliesWithSolanaDappStorePolicies, requestorIsAuthorized, criticalUpdate: critical, + alphaTest, }, dryRun ); diff --git a/packages/cli/src/config/PublishDetails.ts b/packages/cli/src/config/PublishDetails.ts index 743f053..a975b32 100644 --- a/packages/cli/src/config/PublishDetails.ts +++ b/packages/cli/src/config/PublishDetails.ts @@ -20,6 +20,7 @@ import util from "util"; import { imageSize } from "image-size"; import { exec } from "child_process"; import getVideoDimensions from "get-video-dimensions"; +import { PublicKey } from "@solana/web3.js"; const runImgSize = util.promisify(imageSize); const runExec = util.promisify(exec); @@ -179,6 +180,17 @@ export const loadPublishDetailsWithChecks = async ( } } + const { alpha_testers } = config.solana_mobile_dapp_publisher_portal; + if (alpha_testers !== undefined) { + for (const wallet of alpha_testers.split(",")) { + try { + void new PublicKey(wallet); + } catch (e: unknown) { + throw new Error(`invalid alpha tester wallet <${wallet}>`); + } + } + } + return config; }; diff --git a/packages/cli/src/prebuild_schema/publishing_source.yaml b/packages/cli/src/prebuild_schema/publishing_source.yaml index 794562b..3338696 100644 --- a/packages/cli/src/prebuild_schema/publishing_source.yaml +++ b/packages/cli/src/prebuild_schema/publishing_source.yaml @@ -51,4 +51,5 @@ release: solana_mobile_dapp_publisher_portal: google_store_package: <> testing_instructions: >- - <> \ No newline at end of file + <> + alpha_testers: <> \ No newline at end of file diff --git a/packages/core/src/publish/PublishCoreSubmit.ts b/packages/core/src/publish/PublishCoreSubmit.ts index 76bcdb8..6eec19d 100644 --- a/packages/core/src/publish/PublishCoreSubmit.ts +++ b/packages/core/src/publish/PublishCoreSubmit.ts @@ -8,6 +8,8 @@ import { CONTACT_PROPERTY_WEBSITE, submitRequestToSolanaDappPublisherPortal, TICKET_OBJECT_ID, + TICKET_PROPERTY_ALPHA_TEST, + TICKET_PROPERTY_ALPHA_TESTERS, TICKET_PROPERTY_ATTESTATION_PAYLOAD, TICKET_PROPERTY_AUTHORIZED_REQUEST, TICKET_PROPERTY_DAPP_COLLECTION_ACCOUNT_ADDRESS, @@ -28,7 +30,8 @@ const createSubmitRequest = async ( publisherDetails: Publisher, solanaMobileDappPublisherPortalDetails: SolanaMobileDappPublisherPortal, compliesWithSolanaDappStorePolicies: boolean, - requestorIsAuthorized: boolean + requestorIsAuthorized: boolean, + alphaTest?: boolean ) => { const { attestationPayload, requestUniqueId } = await createAttestationPayload(connection, sign); @@ -90,6 +93,14 @@ const createSubmitRequest = async ( }); } + if (alphaTest) { + request.fields.push({ + objectTypeId: TICKET_OBJECT_ID, + name: TICKET_PROPERTY_ALPHA_TEST, + value: true, + }); + } + if (solanaMobileDappPublisherPortalDetails.testing_instructions !== undefined) { request.fields.push( { @@ -100,6 +111,14 @@ const createSubmitRequest = async ( ); } + if (solanaMobileDappPublisherPortalDetails.alpha_testers !== undefined) { + request.fields.push({ + objectTypeId: TICKET_OBJECT_ID, + name: TICKET_PROPERTY_ALPHA_TESTERS, + value: solanaMobileDappPublisherPortalDetails.alpha_testers, + }); + } + return request; }; @@ -110,6 +129,7 @@ export type PublishSubmitInput = { solanaMobileDappPublisherPortalDetails: SolanaMobileDappPublisherPortal; compliesWithSolanaDappStorePolicies: boolean; requestorIsAuthorized: boolean; + alphaTest?: boolean; }; export const publishSubmit = async ( @@ -121,6 +141,7 @@ export const publishSubmit = async ( solanaMobileDappPublisherPortalDetails, compliesWithSolanaDappStorePolicies, requestorIsAuthorized, + alphaTest, } : PublishSubmitInput, dryRun: boolean, ) => { @@ -132,7 +153,9 @@ export const publishSubmit = async ( publisherDetails, solanaMobileDappPublisherPortalDetails, compliesWithSolanaDappStorePolicies, - requestorIsAuthorized); + requestorIsAuthorized, + alphaTest + ); return submitRequestToSolanaDappPublisherPortal(submitRequest, URL_FORM_SUBMIT, dryRun); }; diff --git a/packages/core/src/publish/PublishCoreUpdate.ts b/packages/core/src/publish/PublishCoreUpdate.ts index fe1713d..a965290 100644 --- a/packages/core/src/publish/PublishCoreUpdate.ts +++ b/packages/core/src/publish/PublishCoreUpdate.ts @@ -8,6 +8,8 @@ import { CONTACT_PROPERTY_WEBSITE, submitRequestToSolanaDappPublisherPortal, TICKET_OBJECT_ID, + TICKET_PROPERTY_ALPHA_TEST, + TICKET_PROPERTY_ALPHA_TESTERS, TICKET_PROPERTY_ATTESTATION_PAYLOAD, TICKET_PROPERTY_AUTHORIZED_REQUEST, TICKET_PROPERTY_CRITICAL_UPDATE, @@ -29,7 +31,8 @@ const createUpdateRequest = async ( solanaMobileDappPublisherPortalDetails: SolanaMobileDappPublisherPortal, compliesWithSolanaDappStorePolicies: boolean, requestorIsAuthorized: boolean, - criticalUpdate: boolean + criticalUpdate: boolean, + alphaTest?: boolean ) => { const { attestationPayload, requestUniqueId } = await createAttestationPayload(connection, sign); @@ -93,6 +96,14 @@ const createUpdateRequest = async ( ); } + if (alphaTest) { + request.fields.push({ + objectTypeId: TICKET_OBJECT_ID, + name: TICKET_PROPERTY_ALPHA_TEST, + value: true, + }); + } + if (solanaMobileDappPublisherPortalDetails.testing_instructions !== undefined) { request.fields.push( { @@ -103,6 +114,14 @@ const createUpdateRequest = async ( ); } + if (solanaMobileDappPublisherPortalDetails.alpha_testers !== undefined) { + request.fields.push({ + objectTypeId: TICKET_OBJECT_ID, + name: TICKET_PROPERTY_ALPHA_TESTERS, + value: solanaMobileDappPublisherPortalDetails.alpha_testers, + }); + } + return request; }; @@ -114,6 +133,7 @@ export type PublishUpdateInput = { compliesWithSolanaDappStorePolicies: boolean; requestorIsAuthorized: boolean; criticalUpdate: boolean; + alphaTest?: boolean; }; export const publishUpdate = async ( @@ -126,6 +146,7 @@ export const publishUpdate = async ( compliesWithSolanaDappStorePolicies, requestorIsAuthorized, criticalUpdate, + alphaTest, } : PublishUpdateInput, dryRun: boolean, ) => { @@ -138,7 +159,9 @@ export const publishUpdate = async ( solanaMobileDappPublisherPortalDetails, compliesWithSolanaDappStorePolicies, requestorIsAuthorized, - criticalUpdate); + criticalUpdate, + alphaTest + ); return submitRequestToSolanaDappPublisherPortal(updateRequest, URL_FORM_UPDATE, dryRun); }; diff --git a/packages/core/src/publish/dapp_publisher_portal.ts b/packages/core/src/publish/dapp_publisher_portal.ts index 83b4ac5..ec12af8 100644 --- a/packages/core/src/publish/dapp_publisher_portal.ts +++ b/packages/core/src/publish/dapp_publisher_portal.ts @@ -18,6 +18,8 @@ export const TICKET_PROPERTY_GOOGLE_PLAY_STORE_PACKAGE_NAME = "google_play_store export const TICKET_PROPERTY_POLICY_COMPLIANT = "complies_with_solana_dapp_store_policies"; // boolean export const TICKET_PROPERTY_REQUEST_UNIQUE_ID = "request_unique_id"; // string (32 base-10 digits) export const TICKET_PROPERTY_TESTING_INSTRUCTIONS = "testing_instructions"; // string +export const TICKET_PROPERTY_ALPHA_TEST = "alpha_test"; // boolean +export const TICKET_PROPERTY_ALPHA_TESTERS = "alpha_testers"; // string export const FORM_SUBMIT = "1464247f-6804-46e1-8114-952f372daa81"; export const FORM_UPDATE = "87b4cbe7-957f-495c-a132-8b789678883d"; diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 914b742..f6716dd 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -84,6 +84,7 @@ export type Release = { export type SolanaMobileDappPublisherPortal = { google_store_package: string; testing_instructions: string; + alpha_testers?: string; }; export type LastSubmittedVersionOnChain = {