From 0f2471a7b4e4d79dbcc2187088c5a2e3b1e22ee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20D=C3=ADaz?= Date: Fri, 6 Dec 2024 10:03:16 -0300 Subject: [PATCH] feat: Track installation source (#86) --- .github/workflows/store-release.yml | 116 ++++++++++++++++++++++++++++ electron-store-builder.cjs | 16 ++++ packages/main/src/helpers.ts | 6 ++ packages/main/src/modules/ipc.ts | 4 +- 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/store-release.yml create mode 100644 electron-store-builder.cjs diff --git a/.github/workflows/store-release.yml b/.github/workflows/store-release.yml new file mode 100644 index 0000000..385dceb --- /dev/null +++ b/.github/workflows/store-release.yml @@ -0,0 +1,116 @@ +name: Store Release + +on: + release: + types: + - published + +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + shell: 'bash' + +jobs: + strategy: + fail-fast: true + matrix: + os: [ macos-latest, windows-latest ] + store: [ itch.io ] + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + cache: 'npm' + + - name: Install dependencies + run: npm ci + env: + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 + + - name: Get Release Tag + id: release_tag + run: | + echo "RELEASE_TAG=${GITHUB_REF##*/}" >> $GITHUB_OUTPUT + + - name: Build Release for ${{ matrix.store }} + run: npm run build + env: + MODE: production + VITE_PROVIDER: ${{ matrix.store }} + # Segment API Key + VITE_SEGMENT_API_KEY: ${{ secrets.SEGMENT_API_KEY }} + # Sentry AUTH Token + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + VITE_SENTRY_DSN: ${{ secrets.SENTRY_DSN }} + # AWS Secrets + VITE_AWS_ACCESS_KEY_ID: ${{ secrets.EXPLORER_TEAM_AWS_ACCESS_KEY_ID }} + VITE_AWS_SECRET_ACCESS_KEY: ${{ secrets.EXPLORER_TEAM_AWS_SECRET_ACCESS_KEY }} + VITE_AWS_DEFAULT_REGION: ${{ secrets.EXPLORER_TEAM_AWS_DEFAULT_REGION }} + VITE_AWS_S3_BUCKET: ${{ secrets.EXPLORER_TEAM_S3_BUCKET }} + VITE_AWS_S3_BUCKET_PUBLIC_URL: ${{ vars.EXPLORER_TEAM_S3_BUCKET_PUBLIC_URL }} + + # Download 'SSLcom/esigner-codesign' to a folder called 'esigner-codesign' in the root of the project + - name: Checkout esigner-codesign repository (Windows) + if: ${{ matrix.os == 'windows-latest' }} + uses: actions/checkout@v3 + with: + repository: 'SSLcom/esigner-codesign' + path: esigner-codesign + + - name: Compile artifacts and upload them to S3 + # I use this action because it is capable of retrying multiple times if there are any issues with the distribution server + uses: nick-fields/retry@v3 + with: + timeout_minutes: 15 + max_attempts: 6 + retry_wait_seconds: 15 + retry_on: error + shell: 'bash' + command: npx electron-builder --config electron-store-builder.cjs \ + -c.extraMetadata.version=${{ steps.release_tag.outputs.release_tag }} \ + -c.mac.notarize.teamId=${{ env.APPLE_TEAM_ID }} \ + --publish always + env: + # Code Signing params + # See https://www.electron.build/code-signing + CSC_LINK: ${{ secrets.MACOS_CSC_LINK }} + CSC_KEY_PASSWORD: ${{ secrets.MACOS_CSC_KEY_PASSWORD }} + # Notarization params + # See https://www.electron.build/configuration/mac#NotarizeNotaryOptions + APPLE_ID: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }} + APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.MACOS_NOTARIZATION_PWD }} + APPLE_TEAM_ID: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }} + # Publishing artifacts + RELEASE_TAG: ${{ steps.release_tag.outputs.release_tag }} + GH_TOKEN: ${{ secrets.github_token }} # GitHub token, automatically provided (No need to define this secret in the repo settings) + # The following are the parameters required by the esigner-codesign action to work, we must explicitly pass in even the optional ones since we're not using the action directly, but from the checked out repo + CODE_SIGN_SCRIPT_PATH: "${{ github.workspace }}\\esigner-codesign\\dist\\index.js" + INPUT_COMMAND: "sign" + INPUT_FILE_PATH: "${{ github.workspace }}\\dist\\Decentraland Launcher-win-x64.exe" + INPUT_OVERRIDE: "true" + INPUT_MALWARE_BLOCK: "false" + INPUT_CLEAN_LOGS: "false" + INPUT_JVM_MAX_MEMORY: "1024M" + INPUT_ENVIRONMENT_NAME: "PROD" + INPUT_USERNAME: ${{ secrets.ES_USERNAME }} + INPUT_PASSWORD: ${{ secrets.ES_PASSWORD }} + INPUT_TOTP_SECRET: ${{ secrets.ES_TOTP_SECRET }} + INPUT_CREDENTIAL_ID: ${{ secrets.WINDOWS_CREDENTIAL_ID_SIGNER }} + # S3 Params + PROVIDER: ${{ matrix.store }} + AWS_ACCESS_KEY_ID: ${{ secrets.EXPLORER_TEAM_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.EXPLORER_TEAM_AWS_SECRET_ACCESS_KEY }} + AWS_S3_BUCKET: ${{ secrets.EXPLORER_TEAM_S3_BUCKET }} + AWS_DEFAULT_REGION: ${{ secrets.EXPLORER_TEAM_AWS_DEFAULT_REGION }} diff --git a/electron-store-builder.cjs b/electron-store-builder.cjs new file mode 100644 index 0000000..7fdf8a5 --- /dev/null +++ b/electron-store-builder.cjs @@ -0,0 +1,16 @@ +const baseConfig = require('./electron-builder.cjs'); + +const config = { + ...baseConfig, + publish: [ + { + provider: 's3', + bucket: process.env.AWS_S3_BUCKET, + endpoint: process.env.AWS_ENDPOINT_URL, + region: process.env.AWS_DEFAULT_REGION, + path: `/launcher/${process.env.PROVIDER}/releases/${process.env.RELEASE_TAG}/`, + }, + ], +}; + +module.exports = config; diff --git a/packages/main/src/helpers.ts b/packages/main/src/helpers.ts index 432332d..d2cca76 100644 --- a/packages/main/src/helpers.ts +++ b/packages/main/src/helpers.ts @@ -6,6 +6,8 @@ import JSZip from 'jszip'; import { extract, list } from 'tar'; import semver from 'semver'; +const DEFAULT_PROVIDER = 'dcl'; + export function getAppVersion(): string { return app.getVersion(); } @@ -165,3 +167,7 @@ export function compareVersions(version1: string, version2: string) { const result = semver.compare(version1, version2); return result > 0; } + +export function getProvider() { + return import.meta.env.VITE_PROVIDER || DEFAULT_PROVIDER; +} diff --git a/packages/main/src/modules/ipc.ts b/packages/main/src/modules/ipc.ts index ec20a90..8b30008 100644 --- a/packages/main/src/modules/ipc.ts +++ b/packages/main/src/modules/ipc.ts @@ -15,7 +15,7 @@ import { getBucketURL, RELEASE_PREFIX, } from '#shared'; -import { getAppBasePath, decompressFile, getOSName, isAppUpdated, PLATFORM, getAppVersion } from '../helpers'; +import { getAppBasePath, decompressFile, getOSName, isAppUpdated, PLATFORM, getAppVersion, getProvider } from '../helpers'; import { getUserId } from './config'; const EXPLORER_PATH = join(getAppBasePath(), 'Explorer'); @@ -220,6 +220,8 @@ export async function launchExplorer(event: Electron.IpcMainInvokeEvent, version analytics.getAnonymousId(), '--session_id', analytics.getSessionId(), + '--provider', + getProvider(), ].filter(arg => !!arg); log.info('[Main Window][IPC][LaunchExplorer] Opening the Explorer', explorerParams); spawn(explorerBinPath, explorerParams, { cwd: explorerBinDir, detached: true, stdio: 'ignore' })