Skip to content

Commit

Permalink
feat: add preview deployment to pr
Browse files Browse the repository at this point in the history
  • Loading branch information
nikaaru authored and yeager-eren committed Apr 9, 2024
1 parent 84367b4 commit bc36e7a
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 14 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,50 @@ jobs:
run: node ./scripts/check-conventional-commits/command.mjs
env:
REF: ${{ github.ref }}

# for preview deployment for specific project, add vercel project id in environment section
- name: Preview Deployment
id: deploy
run: |
yarn global add vercel
yarn run deploy
env:
REF: ${{ github.ref }}
GH_TOKEN: ${{ github.token }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_PROJECT_WIDGET_CONFIG: ${{ secrets.VERCEL_PROJECT_WIDGET_CONFIG }} # widget playground
VERCEL_PROJECT_WIDGET_APP: ${{ secrets.VERCEL_PROJECT_WIDGET_APP }} # widget app
ENABLE_PREVIEW_DEPLOY: true

outputs:
# the structure of output variable is {packageNameWithoutScope}-url like: widget-app-url
app_url: ${{ steps.deploy.outputs.widget-app-url }}
playground_url: ${{ steps.deploy.outputs.widget-playground-url }}

# add job for each project that you want has preview deployment
app-preview:
runs-on: ubuntu-latest
needs: check
environment:
name: app-preview
url: ${{ steps.seturl.outputs.url }}
steps:
- name: Extract Preview URL
id: seturl
run: |
echo "url=${{ needs.check.outputs.app_url }}">> $GITHUB_OUTPUT
echo "Preview URL: ${{ needs.check.outputs.app_url}}"
playground-preview:
runs-on: ubuntu-latest
needs: check
environment:
name: playground-preview
url: ${{ steps.seturl.outputs.url }}
steps:
- name: Extract Preview URL
id: seturl
run: |
echo "url=${{ needs.check.outputs.playground_url }}">> $GITHUB_OUTPUT
echo "Preview URL: ${{ needs.check.outputs.playground_url}}"
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"typescript": "^5.3.3"
},
"devDependencies": {
"@actions/core": "^1.10.1",
"@babel/core": "^7.22.5",
"@commitlint/cli": "^18.6.1",
"@commitlint/config-conventional": "^18.6.2",
Expand Down
7 changes: 7 additions & 0 deletions scripts/common/errors.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,11 @@ export class CrowdinError extends Error {
constructor(msg) {
super(msg);
}
}

export class VercelError extends Error {
name = 'VercelError';
constructor(msg) {
super(msg);
}
}
21 changes: 21 additions & 0 deletions scripts/common/github.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,27 @@ export async function createPullRequest(pr) {
return output;
}

export async function createComment(comment) {
const {commentBody, issueNumber} = comment;

if (!issueNumber || !commentBody) {
throw new GithubCommandError(
'Creating comment cannot proceed without required parameters. \n',
JSON.stringify({ issueNumber, commentBody })
);
}

const output = await execa('gh', ['issue', 'comment', issueNumber, '--body', commentBody])
.then(({ stdout }) => stdout)
.catch((err) => {
throw new GithubCommandError(
`Failed to add comment to issue. \n ${err.stdout || err} \n`
);
});

return output;
}

export function checkEnvironments() {
const envs = {
NPM_TOKEN: !!process.env.NPM_TOKEN,
Expand Down
18 changes: 7 additions & 11 deletions scripts/deploy/command.mjs
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
#!/usr/bin/env node
'use strict';
import process from 'node:process';
import { workspacePackages } from '../common/utils.mjs';
import { build } from '../publish/build.mjs';
import { logAsSection } from '../publish/utils.mjs';
import { deployProjectsToVercel } from './utils.mjs';
import { deployProjectsToVercel, getClientsListToBeDeployed } from './utils.mjs';


const EXCLUDED_PACKAGES = ['@rango-dev/widget-iframe'];

// TODO: Working directory should be empty.
async function run() {
// Detect last release and what packages has changed since then.
const packages = await workspacePackages();
const privatePackages = packages.filter((pkg) => {
if (EXCLUDED_PACKAGES.includes(pkg.name)) return false;
return pkg.private;
});

const listPackagesToBeDeployed = await getClientsListToBeDeployed();
logAsSection('[x] Check Environment');

await build(privatePackages).catch((e) => {
await build(listPackagesToBeDeployed).catch((e) => {
console.log(
'[-] BUILD FAILED. Ignore it to workflow run the rest of tasks.'
);
throw e;
});
logAsSection('[x] Build for VERCEL');
await deployProjectsToVercel(privatePackages).catch((e) => {
await deployProjectsToVercel(listPackagesToBeDeployed).catch((e) => {
console.log(
'[-] DEPLOY FAILED. Ignore it to workflow run the rest of tasks.'
);
Expand Down
3 changes: 3 additions & 0 deletions scripts/deploy/config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import process from 'node:process';
const scope = `@rango-dev`;
export const VERCEL_ORG_ID = process.env.VERCEL_ORG_ID;
export const VERCEL_TOKEN = process.env.VERCEL_TOKEN;
export const ENABLE_PREVIEW_DEPLOY = process.env.ENABLE_PREVIEW_DEPLOY;
export const EXCLUDED_PACKAGES = ['@rango-dev/widget-iframe'];

export const VERCEL_PACKAGES = {
[`${scope}/wallets-demo`]: getEnvWithFallback('VERCEL_PROJECT_WALLETS'),
[`${scope}/queue-manager-demo`]: getEnvWithFallback('VERCEL_PROJECT_Q'),
Expand Down
67 changes: 64 additions & 3 deletions scripts/deploy/utils.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { execa } from 'execa';
import { detectChannel } from '../common/github.mjs';
import { VERCEL_ORG_ID, VERCEL_PACKAGES, VERCEL_TOKEN } from './config.mjs';
import { ENABLE_PREVIEW_DEPLOY, EXCLUDED_PACKAGES, VERCEL_ORG_ID, VERCEL_PACKAGES, VERCEL_TOKEN } from './config.mjs';
import * as actionCore from '@actions/core';
import { VercelError } from '../common/errors.mjs';
import { packageNameWithoutScope, workspacePackages } from '../common/utils.mjs';

export function getVercelProjectId(packageName) {
return VERCEL_PACKAGES[packageName];
Expand Down Expand Up @@ -37,15 +40,38 @@ export async function deploySingleProjectToVercel(pkg) {
],
{ env }
);

await execa(
'vercel',
['build', '--cwd', pkg.location, '--token', VERCEL_TOKEN],
{ env }
);
await execa('vercel', [pkg.location, '--prebuilt', '--token', VERCEL_TOKEN], {
env,

const vercelResult = await execa(
'vercel',
[pkg.location, '--prebuilt', '--token', VERCEL_TOKEN],
{ env }
).then((result) => result.stdout)
.catch((err) => {
throw new VercelError(
`An error occurred on deploy ${pkg.name} package \n ${err.message} \n ${err.stderr}`
);
});

// Run tail -1 on the stdout to get the last line, because `vercel` command returns the URL in the last line.
const uRLPreview = await execa('tail', ['-1'], { input: vercelResult })
.then(result => result.stdout)
.catch((err) => {
throw new VercelError(
`An error occurred on get url preview for ${pkg.name} package \n ${err.message} \n ${err.stderr}`
);
});

// set package name and url preview to github output for use in workflow
const tagName = packageNameWithoutScope(pkg.name);
actionCore.setOutput(`${tagName}-url`, uRLPreview);

console.log(`${tagName}-url:`, uRLPreview);
console.log(`${pkg.name} deployed.`);
}

Expand All @@ -67,3 +93,38 @@ export function groupPackagesForDeploy(packages) {

return output;
}

export async function getClientsListToBeDeployed(){
/*
Deploys packages based on the state of the `ENABLE_PREVIEW_DEPLOY` environment variable.
if ENABLE_PREVIEW_DEPLOY is true, only packages that has project id in workflow environments will be deployed.
else private packages will be deployed.
*/

// Detect last release and what packages has changed since then.
const packages = await workspacePackages();
const listPackagesToBeDeployed = packages.filter((pkg) => {
if (EXCLUDED_PACKAGES.includes(pkg.name)) return false;

if (ENABLE_PREVIEW_DEPLOY) {
const hasProjectId = getVercelProjectId(pkg.name) && getVercelProjectId(pkg.name) !== 'NOT SET' ;
return pkg.private && hasProjectId;
}
else {
return pkg.private;
}
});

if(ENABLE_PREVIEW_DEPLOY){
console.log('preview deployment is enabled.');
console.log('these packages will be deployed:', listPackagesToBeDeployed.map(pkg=>pkg.name).join(', '));
console.log('note: if you need add more packages to be deployed, first you need to add vercel project id to workflow environments then follow documentation there.');
}
else{
console.log('preview deployment is disabled.');
console.log('these packages will be deployed:', listPackagesToBeDeployed.map(pkg=>pkg.name).join(', '));
}


return listPackagesToBeDeployed;
}
33 changes: 33 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@
resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf"
integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==

"@actions/core@^1.10.1":
version "1.10.1"
resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.10.1.tgz#61108e7ac40acae95ee36da074fa5850ca4ced8a"
integrity sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g==
dependencies:
"@actions/http-client" "^2.0.1"
uuid "^8.3.2"

"@actions/http-client@^2.0.1":
version "2.2.1"
resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-2.2.1.tgz#ed3fe7a5a6d317ac1d39886b0bb999ded229bb38"
integrity sha512-KhC/cZsq7f8I4LfZSJKgCvEwfkE8o1538VoBeoGzokVLLnbFDEAdFD3UhoMklxo2un9NJVBdANOresx7vTHlHw==
dependencies:
tunnel "^0.0.6"
undici "^5.25.4"

"@adraffy/[email protected]":
version "1.10.0"
resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7"
Expand Down Expand Up @@ -2561,6 +2577,11 @@
resolved "https://registry.yarnpkg.com/@fal-works/esbuild-plugin-global-externals/-/esbuild-plugin-global-externals-2.1.2.tgz#c05ed35ad82df8e6ac616c68b92c2282bd083ba4"
integrity sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==

"@fastify/busboy@^2.0.0":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d"
integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==

"@floating-ui/core@^1.4.2":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.0.tgz#5c05c60d5ae2d05101c3021c1a2a350ddc027f8c"
Expand Down Expand Up @@ -17305,6 +17326,11 @@ tunnel-agent@^0.6.0:
dependencies:
safe-buffer "^5.0.1"

tunnel@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==

tweetnacl-util@^0.15.1:
version "0.15.1"
resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b"
Expand Down Expand Up @@ -17519,6 +17545,13 @@ undici-types@~5.26.4:
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==

undici@^5.25.4:
version "5.28.4"
resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068"
integrity sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==
dependencies:
"@fastify/busboy" "^2.0.0"

unenv@^1.7.4:
version "1.8.0"
resolved "https://registry.yarnpkg.com/unenv/-/unenv-1.8.0.tgz#0f860d5278405700bd95d47b23bc01f3a735d68c"
Expand Down

0 comments on commit bc36e7a

Please sign in to comment.