diff --git a/build/preview-comment/index.js b/build/preview-comment/index.js index aa770227..898f1f1f 100644 --- a/build/preview-comment/index.js +++ b/build/preview-comment/index.js @@ -15785,6 +15785,7 @@ async function commentAction(input = commentInput()) { } const variables = { projectLink: (0, expo_1.projectLink)(project, input.channel), + projectDeepLink: (0, expo_1.projectDeepLink)(project, input.channel), projectName: project.name, projectOwner: project.owner || '', projectQR: (0, expo_1.projectQR)(project, input.channel), @@ -15828,7 +15829,7 @@ function template(template, replacements) { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.projectLink = exports.projectQR = exports.projectInfo = exports.projectOwner = exports.authenticate = void 0; +exports.projectDeepLink = exports.projectLink = exports.projectQR = exports.projectInfo = exports.projectOwner = exports.authenticate = void 0; const core_1 = __nccwpck_require__(2186); const exec_1 = __nccwpck_require__(1514); const io_1 = __nccwpck_require__(7436); @@ -15915,6 +15916,18 @@ function projectLink(project, channel) { return url.toString(); } exports.projectLink = projectLink; +/** + * Create a deep link to open the project in Expo Go + */ +function projectDeepLink(project, channel) { + (0, assert_1.ok)(project.owner, 'Could not create a deep link for project without owner'); + const url = new url_1.URL(`exp://exp.host/@${project.owner}/${project.slug}`); + if (channel) { + url.searchParams.append('release-channel', channel); + } + return url.toString(); +} +exports.projectDeepLink = projectDeepLink; /***/ }), diff --git a/build/setup/index.js b/build/setup/index.js index 793b8f0b..fe06121a 100644 --- a/build/setup/index.js +++ b/build/setup/index.js @@ -66905,7 +66905,7 @@ exports.handleCacheError = handleCacheError; "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.projectLink = exports.projectQR = exports.projectInfo = exports.projectOwner = exports.authenticate = void 0; +exports.projectDeepLink = exports.projectLink = exports.projectQR = exports.projectInfo = exports.projectOwner = exports.authenticate = void 0; const core_1 = __nccwpck_require__(2186); const exec_1 = __nccwpck_require__(1514); const io_1 = __nccwpck_require__(7436); @@ -66992,6 +66992,18 @@ function projectLink(project, channel) { return url.toString(); } exports.projectLink = projectLink; +/** + * Create a deep link to open the project in Expo Go + */ +function projectDeepLink(project, channel) { + (0, assert_1.ok)(project.owner, 'Could not create a deep link for project without owner'); + const url = new url_1.URL(`exp://exp.host/@${project.owner}/${project.slug}`); + if (channel) { + url.searchParams.append('release-channel', channel); + } + return url.toString(); +} +exports.projectDeepLink = projectDeepLink; /***/ }), diff --git a/preview-comment/README.md b/preview-comment/README.md index 45f2605c..4fc2cc42 100644 --- a/preview-comment/README.md +++ b/preview-comment/README.md @@ -52,16 +52,17 @@ There are a few variables available to generate the comment content. Some of these variables are also exported as subaction output. Here is a summary of these variables. -| output name | template name | description | -| ---------------- | ---------------- | ---------------------------------------------------- | -| **projectOwner** | `{projectOwner}` | The resolved owner of the project | -| **projectSlug** | `{projectSlug}` | The resolved slug of the project | -| **projectName** | `{projectName}` | The resolved name of the project | -| **projectLink** | `{projectLink}` | The expo.dev project link, including release channel | -| **projectQR** | `{projectQR}` | The QR code link, to load the project in Expo Go | -| - | `{channel}` | The release channel that was used | -| **message** | - | The resolved message content | -| **messageId** | - | The resolved message id content | +| output name | template name | description | +| ---------------- | ---------------- | ----------------------------------------------------- | +| **projectOwner** | `{projectOwner}` | The resolved owner of the project | +| **projectSlug** | `{projectSlug}` | The resolved slug of the project | +| **projectName** | `{projectName}` | The resolved name of the project | +| **projectDeepLink** | `{projectDeepLink}` | A deep link to open the project in Expo Go | +| **projectLink** | `{projectLink}` | The expo.dev project link, including release channel | +| **projectQR** | `{projectQR}` | The QR code link, to load the project in Expo Go | +| - | `{channel}` | The release channel that was used | +| **message** | - | The resolved message content | +| **messageId** | - | The resolved message id content | ## Example workflows diff --git a/src/actions/preview-comment.ts b/src/actions/preview-comment.ts index c78f8a75..ad750c00 100644 --- a/src/actions/preview-comment.ts +++ b/src/actions/preview-comment.ts @@ -1,6 +1,6 @@ import { getBooleanInput, getInput, setOutput, info } from '@actions/core'; -import { projectInfo, projectLink, projectOwner, projectQR } from '../expo'; +import { projectDeepLink, projectInfo, projectLink, projectOwner, projectQR } from '../expo'; import { createIssueComment, pullContext } from '../github'; import { executeAction } from '../worker'; @@ -34,6 +34,7 @@ export async function commentAction(input: CommentInput = commentInput()) { const variables: Record = { projectLink: projectLink(project, input.channel), + projectDeepLink: projectDeepLink(project, input.channel), projectName: project.name, projectOwner: project.owner || '', projectQR: projectQR(project, input.channel), diff --git a/src/expo.ts b/src/expo.ts index 450d766b..8718d972 100644 --- a/src/expo.ts +++ b/src/expo.ts @@ -98,3 +98,17 @@ export function projectLink(project: ProjectInfo, channel?: string): string { return url.toString(); } + +/** + * Create a deep link to open the project in Expo Go + */ +export function projectDeepLink(project: ProjectInfo, channel?: string): string { + assert(project.owner, 'Could not create a deep link for project without owner'); + + const url = new URL(`exp://exp.host/@${project.owner}/${project.slug}`); + if (channel) { + url.searchParams.append('release-channel', channel); + } + + return url.toString(); +} diff --git a/tests/expo.test.ts b/tests/expo.test.ts index 4e62bc68..6453553c 100644 --- a/tests/expo.test.ts +++ b/tests/expo.test.ts @@ -2,7 +2,7 @@ import * as core from '@actions/core'; import * as exec from '@actions/exec'; import * as io from '@actions/io'; -import { authenticate, projectQR, projectLink } from '../src/expo'; +import { authenticate, projectQR, projectLink, projectDeepLink } from '../src/expo'; jest.mock('@actions/core'); jest.mock('@actions/exec'); @@ -68,3 +68,21 @@ describe(projectLink, () => { ); }); }); + +describe(projectDeepLink, () => { + it('throws when owner is undefined', () => { + expect(() => projectDeepLink({ name: 'fakename', slug: 'fakeslug' })).toThrow('without owner'); + }); + + it('returns url with owner and slug', () => { + expect(projectDeepLink({ name: 'fakename', slug: 'fakeslug', owner: 'fakeowner' })).toBe( + 'exp://exp.host/@fakeowner/fakeslug' + ); + }); + + it('returns url with owner, slug, and release channel', () => { + expect(projectDeepLink({ name: 'fakename', slug: 'fakeslug', owner: 'fakeowner' }, 'fakechannel')).toBe( + 'exp://exp.host/@fakeowner/fakeslug?release-channel=fakechannel' + ); + }); +});