Skip to content

Commit

Permalink
Merge branch 'main' into fix/sidebar-padding
Browse files Browse the repository at this point in the history
  • Loading branch information
espenkalle authored Feb 1, 2024
2 parents 7c3782f + 5b27993 commit aca9de2
Show file tree
Hide file tree
Showing 29 changed files with 929 additions and 84 deletions.
19 changes: 19 additions & 0 deletions .github/actions/pnpm-setup/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: PNPM setup
description: 'Set up pnpm with cache'

runs:
using: 'composite'
steps:
- uses: pnpm/action-setup@v2.2.4
with:
version: 8.0.0

- name: Setup Node.js environment
uses: actions/setup-node@v4
with:
node-version: 18
cache: 'pnpm'

- name: Install dependencies
shell: bash
run: pnpm install
13 changes: 13 additions & 0 deletions .github/helpers/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "fusion-workspace-helpers",
"version": "0.0.0",
"type": "module",
"private": true,
"dependencies": {
"@actions/core": "^1.10.1",
"@actions/github": "^6.0.0",
"commander": "^11.1.0",
"markdown-table": "^3.0.3",
"tsx": "^4.6.2"
}
}
1 change: 1 addition & 0 deletions .github/helpers/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const RELEASE_FILE_NAME = 'release.json';
97 changes: 97 additions & 0 deletions .github/helpers/src/issue-checker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/usr/bin/env node

import { Command } from 'commander';
import { getOctokit, context } from '@actions/github';
import { info } from '@actions/core';

const program = new Command();
type Octo = ReturnType<typeof getOctokit>;

program.name('PR');

const noLinkedIssueMessage = `
Howdy, wanderer🌵🤠🐴,
Seems you've sauntered into our GitHub saloon with a pull request, but it appears you've forgotten to tie your horse to the hitching post. Now, in this town, we don't take kindly to stray requests, and the GitHub corral is no place for them.
I reckon you best mosey on over and link that pull request to an issue, lest you want the winds of open source trouble blowin' your way. I've got my eye on you, stranger, and a stern warning echoes through these digital canyons.
Now, for those who might be new to these parts or sufferin' from a bout of forgetfulness, fear not. I've rustled up a guide that's as handy as a snake in a boot🐍🥾. Take a peek at [this guide](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue), and it'll show you the way to tether that pull request like a seasoned rancher🤠.
Don't let the sun set on your unlinked pull request, and remember, in these GitHub lands, the code speaks louder than six-shooters.
Sincerely,
The code patrol👮
`;

program
.command('issue')
.option('-T, --token <token>', 'github token')
.option('-P, --pr <pr>', 'Pull request number')
.action(async (args) => {
if (!args.token) {
throw new Error('Missing github token');
}

if (!args.pr) {
throw new Error('Missing pr number');
}

const client = getOctokit(args.token);
checkIssues(client, parseInt(args.pr));
});

await program.parseAsync();

async function checkIssues(client: Octo, pr: number) {
const pullRequests = await client.graphql(
`
query($owner: String!, $name: String!, $pr: Int!) {
repository(owner: $owner, name: $name) {
pullRequest(number: $pr) {
id
number
title
timelineItems(first: 100, itemTypes: [CONNECTED_EVENT, CROSS_REFERENCED_EVENT]) {
__typename
... on PullRequestTimelineItemsConnection{
totalCount
nodes {
__typename
... on ConnectedEvent {
source {
__typename
... on PullRequest {
number
}
}
subject {
__typename
... on PullRequest {
number
}
}
}
}
}
}
}
}
}`,
{ owner: context.repo.owner, name: context.repo.repo, pr: pr }
);

const linkedIssues: number = (pullRequests as any).repository.pullRequest.timelineItems.totalCount;

if (linkedIssues === 0) {
info(`No linked issues adding comment to pr ${pr}`);
const comment = await client.rest.issues.createComment({
issue_number: pr,
body: noLinkedIssueMessage,
owner: context.issue.owner,
repo: context.issue.repo,
});
return;
}
info(`Linked issues: ${linkedIssues}`);
}
89 changes: 89 additions & 0 deletions .github/helpers/src/pre-version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/usr/bin/env node

const defaultReleaseSchema: ReleaseSchema = {
packages: [],
};

import { Command } from 'commander';
import { execSync } from 'child_process';
import { writeFileSync, existsSync, readFileSync } from 'fs';
import { parsePackageJson } from './utils/parse-package-json.js';
import { logInfo } from './utils/logInfo.js';
import { RELEASE_FILE_NAME } from './constants.js';

const program = new Command();

program.name('PR');

program.command('publish').action(async () => {
createFusionApp();
});

await program.parseAsync();

/**
* Returns the next patch of packagejson version
*/
function packageJsonNextPatch() {
const packageJson = parsePackageJson();
const version = packageJson.version.split('-')[0];

const splitVersion = version.split('.');

splitVersion[2] = (parseInt(splitVersion[2]) + 1).toString();
return splitVersion.join('.');
}

export async function createFusionApp() {
preparePackageForVerBump();
bumpPackageJson();
publishPrPackage();
}

function publishPrPackage() {
const releaseMessage = execSync('pnpm publish --tag pr --json --no-git-checks');

const npmRelease: NpmRelease = JSON.parse(releaseMessage.toString('utf-8'));
logInfo(npmRelease.id, 'Green');
appendReleaseLog(npmRelease);
}

type ReleaseSchema = {
packages: string[];
};

function appendReleaseLog(npmRelease: NpmRelease) {
const fileName = `../../${RELEASE_FILE_NAME}`;
if (!existsSync(fileName)) {
writeFileSync(fileName, JSON.stringify(defaultReleaseSchema, null, 2));
}
const release = readFileSync(fileName).toString('utf-8');
const contents: ReleaseSchema = JSON.parse(release);
contents.packages.push(npmRelease.id);
writeFileSync(fileName, JSON.stringify(contents));
}

function preparePackageForVerBump() {
const packageJson = parsePackageJson();
const nextPatch = packageJsonNextPatch();
const maybeVersion = execSync(`pnpm show ${packageJson.name} --json dist-tags.pr`).toString('utf-8');

if (maybeVersion === '') return;

//There is a pr tag release including the package json ver
if (maybeVersion.includes(nextPatch)) {
packageJson.version = maybeVersion.replaceAll(`"`, '');
writeFileSync('./package.json', JSON.stringify(packageJson, null, 2));
}
}

function bumpPackageJson() {
execSync('pnpm version prerelease --preid pr');
}

type NpmRelease = {
id: string;
name: string;
version: number;
unpackedSize: number;
};
90 changes: 90 additions & 0 deletions .github/helpers/src/publish-comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/usr/bin/env node

import { Command } from 'commander';
import { getOctokit, context } from '@actions/github';
import { setSecret } from '@actions/core';
import { logInfo } from './utils/logInfo.js';
import { readFileSync } from 'fs';
import { RELEASE_FILE_NAME } from './constants.js';

type Octo = ReturnType<typeof getOctokit>;

async function getPullRequestFromBranch(client: Octo) {
const branch = context.ref.replace('refs/heads/', '');

const pullRequests = await client.rest.pulls.list({ owner: context.issue.owner, repo: context.issue.repo });
const pullRequest = pullRequests.data.find((s) => s.head.ref === branch);

if (!pullRequest) {
const msg = `${branch} does not have any associated pull request`;
logInfo(msg, 'Red');
throw new Error(msg);
}
return pullRequest;
}

async function commentPullRequest(client: Octo, issueNumber: number) {
const body = parseReleaseJson();

const comment = await client.rest.issues.createComment({
issue_number: issueNumber,
body: body,
owner: context.issue.owner,
repo: context.issue.repo,
});
if (comment.status === 201) {
logInfo('Comment created successfully', 'Green');
}
}

const program = new Command();

program.name('PR');

program
.command('comment')
.option('-T, --token <token>', 'github token')
.action(async (args) => {
if (!args.token) {
throw new Error('Missing github token');
}

setSecret(args.token);
const client = getOctokit(args.token);
const pr = await getPullRequestFromBranch(client);
commentPullRequest(client, pr.number);
});

await program.parseAsync();

function parseReleaseJson() {
const packages: string[] = JSON.parse(readFileSync(`./${RELEASE_FILE_NAME}`).toString('utf-8')).packages;

const isWorkspaceRelease = packages.find((s) => s.includes('workspace-fusion'));

const workspaceWarning = isWorkspaceRelease
? ''
: `Well, I reckon the @equinor/workspace-fusion ain't joinin' the rodeo just yet. Seems like it's taken a rain check on the publication hoedown. Did you happen to forget to give that package a little nudge, like spurrin' a stubborn steer❓`;

const packageLines = packages
.map(
(npmPackage) => `\`\`\`
pnpm i ${npmPackage}
\`\`\``
)
.join('\n');

const prBody = `Howdy, partner,
Looks like you've got yourself a proper roundup with a posse of packages📦. If you're fixin' to bring 'em into your code corral, just hitch 'em up one by one with a trusty command like a cowboy tamin' a wild mustang.
${packageLines}
These here commands will have your packages saddled up and ready to hit the open range of your project. Keep those dependencies roped and ride on into the sunset of seamless coding.
${workspaceWarning}
Happy trailblazin'
`;
return prBody;
}
17 changes: 17 additions & 0 deletions .github/helpers/src/utils/logInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const ColorReset = '\x1b[0m';
type TextColor = 'Red' | 'Green' | 'Black' | 'Yellow' | 'Blue' | 'Magenta' | 'Cyan' | 'White';

const textColor = {
Red: '\x1b[31m',
Black: '\x1b[30m',
Green: '\x1b[32m',
Yellow: '\x1b[33m',
Blue: '\x1b[34m',
Magenta: '\x1b[35m',
Cyan: '\x1b[36m',
White: '\x1b[37m',
} satisfies Record<TextColor, string>;

export function logInfo(message: string, color: TextColor): void {
console.log(`${textColor[color]}${message}${ColorReset}`);
}
12 changes: 12 additions & 0 deletions .github/helpers/src/utils/parse-package-json.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import fs from 'fs';

export type PackageJson = {
name?: string;
version?: string;
type?: 'module' | 'commonjs';
} & Record<string, any>;

export function parsePackageJson(path: string = './package.json'): PackageJson {
const blob = fs.readFileSync(path);
return JSON.parse(blob.toString('utf-8'));
}
8 changes: 8 additions & 0 deletions .github/helpers/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "NodeNext",
"target": "ESNext"
},
"include": ["src"]
}
18 changes: 3 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: CI
name: 🔨CI
on:
push:
branches:
Expand All @@ -13,19 +13,7 @@ jobs:
with:
fetch-depth: 0

- uses: nrwl/nx-set-shas@v4

- name: Setup PNPM
uses: pnpm/action-setup@v2
with:
version: 8

- uses: actions/setup-node@v4
with:
cache: 'pnpm'

- run: pnpm config set auto-install-peers true

- run: npm run first-time-setup
- name: PNPM setup
uses: ./.github/actions/pnpm-setup

- run: pnpm build
Loading

0 comments on commit aca9de2

Please sign in to comment.