Skip to content

Commit

Permalink
Merge pull request #85 from pkgjs/branch-naming
Browse files Browse the repository at this point in the history
  • Loading branch information
dominykas authored Mar 23, 2021
2 parents d7168f5 + d101fd0 commit 3986b2f
Show file tree
Hide file tree
Showing 20 changed files with 400 additions and 320 deletions.
3 changes: 2 additions & 1 deletion lib/clean.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ module.exports = async ({ dependents }, { all, dryRun }) => {

let branches

const branch = await context.getTestingBranchName(parentPkgJSON.name)
const parentBranchName = await context.getParentBranchName()
const branch = await context.getTestingBranchName(parentBranchName)

if (all) {
branches = await github.getWibyBranches(dependentPkgInfo.owner, dependentPkgInfo.name)
Expand Down
17 changes: 14 additions & 3 deletions lib/context.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
'use strict'

const simpleGit = require('simple-git')
const fsPromises = require('fs').promises

exports.getTestingBranchName = async function getTestingBranchName (parentPackageName) {
return `wiby-${parentPackageName}`
exports.getParentBranchName = async function getParentBranchName () {
const { current } = await simpleGit().branch()

return current
}

exports.getTestingBranchName = function getTestingBranchName (parentBranchName) {
return `wiby-${parentBranchName}`
}

exports.getDependencyLink = async function getDependencyLink (owner, repo, commitish) {
return `${owner}/${repo}#${commitish}`
}

exports.getLocalPackageJSON = async function getLocalPackageJSON () {
Expand All @@ -15,7 +26,7 @@ exports.getLocalPackageJSON = async function getLocalPackageJSON () {
The check should search both the dev and peer dependencies to find out if the dependency is
regular, dev or peer.
*/
exports.checkPackageInPackageJSON = function checkPackageInPackageJSON (dep, packageJSON) {
exports.checkDependentUsesParent = function checkDependentUsesParent (dep, packageJSON) {
const dependencyKeyNames = [
'dependencies',
'devDependencies',
Expand Down
5 changes: 3 additions & 2 deletions lib/result.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ module.exports = async function ({ dependents }) {
const dependentPkgJSON = await github.getPackageJson(dependentPkgInfo.owner, dependentPkgInfo.name)
debug(`Dependent module: ${dependentPkgInfo.owner}/${dependentPkgInfo.name}`)

if (!context.checkPackageInPackageJSON(parentPkgJSON.name, dependentPkgJSON)) {
if (!context.checkDependentUsesParent(parentPkgJSON.name, dependentPkgJSON)) {
throw new Error(`${parentPkgInfo.owner}/${parentPkgJSON.name} not found in the package.json of ${dependentPkgInfo.owner}/${dependentPkgInfo.name}`)
}

const branch = await context.getTestingBranchName(parentPkgJSON.name)
const parentBranchName = await context.getParentBranchName()
const branch = await context.getTestingBranchName(parentBranchName)
let resp = await github.getChecks(dependentPkgInfo.owner, dependentPkgInfo.name, branch)
if (resp.data.check_runs.length === 0) {
resp = await github.getCommitStatusesForRef(dependentPkgInfo.owner, dependentPkgInfo.name, branch)
Expand Down
59 changes: 24 additions & 35 deletions lib/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,58 +14,47 @@ module.exports = async function ({ dependents }) {
logger.enableLogs(testCommandNamespace)

const parentPkgJSON = await context.getLocalPackageJSON()
const parentPkgInfo = gitURLParse(parentPkgJSON.repository.url)
debug(`Parent module: ${parentPkgInfo.owner}/${parentPkgJSON.name}`)
const parentRepositoryInfo = gitURLParse(parentPkgJSON.repository.url)
const parentBranchName = await context.getParentBranchName()
debug(`Parent module: ${parentRepositoryInfo.owner}/${parentPkgJSON.name}`)

const commitURL = await getCommitURL(parentPkgInfo.owner, parentPkgInfo.name)
debug('Commit URL to test:', commitURL)
const parentDependencyLink = await context.getDependencyLink(parentRepositoryInfo.owner, parentRepositoryInfo.name, parentBranchName)
debug('Commit URL to test:', parentDependencyLink)

for (const { repository: url } of dependents) {
const dependentPkgInfo = gitURLParse(url)
const dependentPkgJSON = await github.getPackageJson(dependentPkgInfo.owner, dependentPkgInfo.name)
debug(`Dependent module: ${dependentPkgInfo.owner}/${dependentPkgInfo.name}`)
const dependentRepositoryInfo = gitURLParse(url)
const dependentPkgJson = await github.getPackageJson(dependentRepositoryInfo.owner, dependentRepositoryInfo.name)
debug(`Dependent module: ${dependentRepositoryInfo.owner}/${dependentRepositoryInfo.name}`)

if (!context.checkPackageInPackageJSON(parentPkgJSON.name, dependentPkgJSON)) {
throw new Error(`${parentPkgInfo.owner}/${parentPkgJSON.name} not found in the package.json of ${dependentPkgInfo.owner}/${dependentPkgInfo.name}`)
if (!context.checkDependentUsesParent(parentPkgJSON.name, dependentPkgJson)) {
throw new Error(`${parentRepositoryInfo.owner}/${parentPkgJSON.name} not found in the package.json of ${dependentRepositoryInfo.owner}/${dependentRepositoryInfo.name}`)
}

const patchedPackageJSON = applyPatch(commitURL, parentPkgJSON.name, dependentPkgJSON)
await pushPatch(patchedPackageJSON, dependentPkgInfo.owner, dependentPkgInfo.name, parentPkgJSON.name)
const patchedPackageJSON = applyPatch(parentDependencyLink, parentPkgJSON.name, dependentPkgJson, parentPkgJSON.name)
await pushPatch(patchedPackageJSON, dependentRepositoryInfo.owner, dependentRepositoryInfo.name, parentPkgJSON.name, parentBranchName)
}
}

const getCommitHash = async function getCommitHash (owner, repo) {
const [headSha] = await github.getShas(owner, repo)
return headSha
}

const getCommitURL = async function getCommitURL (owner, repo, hash) {
hash = hash || await getCommitHash(owner, repo)

const patch = `${owner}/${repo}#${hash}`
return patch
}

const applyPatch = module.exports.applyPatch =
function applyPatch (patch, module, dependentPkgJSON) {
const dependencyType = context.checkPackageInPackageJSON(module, dependentPkgJSON)
const dependencyType = context.checkDependentUsesParent(module, dependentPkgJSON)
if (!dependencyType) {
throw new Error('Dependency not found in package.json')
}
dependentPkgJSON[dependencyType][module] = patch
return dependentPkgJSON
}

async function pushPatch (packageJSON, owner, repo, dep) {
const file = JSON.stringify(packageJSON, null, 2) + '\n' // assumes package.json is using two spaces
async function pushPatch (dependentPkgJson, dependentOwner, dependentRepo, parentName, parentBranchName) {
const file = JSON.stringify(dependentPkgJson, null, 2) + '\n' // assumes package.json is using two spaces
const encodedFile = Buffer.from(file).toString('base64')
const message = `wiby: update ${dep}`
const branch = await context.getTestingBranchName(dep)

const [headSha, treeSha] = await github.getShas(owner, repo)
const blobSha = await github.createBlob(owner, repo, encodedFile)
const newTreeSha = await github.createTree(owner, repo, treeSha, blobSha)
const commitSha = await github.createCommit(owner, repo, message, newTreeSha, headSha)
await github.createBranch(owner, repo, commitSha, branch)
debug(`Changes pushed to https://github.com/${owner}/${repo}/blob/${branch}/package.json`)
const message = `wiby: update ${parentName}`
const branch = await context.getTestingBranchName(parentBranchName)

const [headSha, treeSha] = await github.getShas(dependentOwner, dependentRepo)
const blobSha = await github.createBlob(dependentOwner, dependentRepo, encodedFile)
const newTreeSha = await github.createTree(dependentOwner, dependentRepo, treeSha, blobSha)
const commitSha = await github.createCommit(dependentOwner, dependentRepo, message, newTreeSha, headSha)
await github.createBranch(dependentOwner, dependentRepo, commitSha, branch)
debug(`Changes pushed to https://github.com/${dependentOwner}/${dependentRepo}/blob/${branch}/package.json`)
}
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@
"git-url-parse": "^11.1.2",
"joi": "^17.2.1",
"node-fetch": "^2.6.0",
"simple-git": "^2.35.1",
"yargs": "^16.0.0"
},
"devDependencies": {
"nock": "^13.0.3",
"standard": "^16.0.0",
"tap": "^14.10.7"
"tap": "^14.10.7",
"tmp": "^0.2.1"
},
"standard": {
"ignore": [
Expand Down
26 changes: 15 additions & 11 deletions test/clean.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,36 @@
require('dotenv').config()
const tap = require('tap')
const nock = require('nock')

const CONFIG = require('./fixtures/config')
const gitFixture = require('./fixtures/git')

const wiby = require('..')

tap.beforeEach(async () => {
nock.disableNetConnect()
})
tap.test('wiby.clean()', async (tap) => {
tap.beforeEach(async () => {
nock.disableNetConnect()
gitFixture.init()
})

tap.afterEach(async () => {
nock.cleanAll()
nock.enableNetConnect()
})
tap.afterEach(async () => {
nock.cleanAll()
nock.enableNetConnect()
})

tap.test('wiby.clean()', async (tap) => {
tap.test('should check if the wiby branch exists', async (tap) => {
nock('https://api.github.com')
.get(`/repos/wiby-test/${CONFIG.DEP_REPO}/branches/wiby-wiby`)
.get(`/repos/wiby-test/${CONFIG.DEP_REPO}/branches/wiby-running-unit-tests`)
.reply(404)

await wiby.clean({ dependents: [{ repository: `https://www.github.com/${CONFIG.DEP_ORG}/${CONFIG.DEP_REPO}` }] }, {})

// implied assertion - no DELETE requests expected - we don't need to delete the missing `wiby-wiby` branch
// implied assertion - no DELETE requests expected - we don't need to delete the missing `wiby-running-unit-tests` branch
})

tap.test('should rethrow when github API inaccessible during branch check', async (tap) => {
nock('https://api.github.com')
.get(`/repos/wiby-test/${CONFIG.DEP_REPO}/branches/wiby-wiby`)
.get(`/repos/wiby-test/${CONFIG.DEP_REPO}/branches/wiby-running-unit-tests`)
.reply(500)

await tap.rejects(
Expand Down
31 changes: 18 additions & 13 deletions test/cli/clean.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,44 @@ const tap = require('tap')
const childProcess = require('child_process')
const path = require('path')

const cwd = path.join(__dirname, '..', '..')
const wibyCommand = path.join(cwd, 'bin', 'wiby')
const gitFixture = require('../fixtures/git')

const wibyCommand = path.join(__dirname, '..', '..', 'bin', 'wiby')
const fixturesPath = path.resolve(path.join(__dirname, '..', 'fixtures'))

tap.test('clean command', async (tap) => {
tap.beforeEach(async () => {
gitFixture.init()
})

tap.test('should delete test branch in all configured test modules', async (tap) => {
const result = childProcess.execSync(`${wibyCommand} clean`, {
cwd: cwd,
env: {
...process.env,
NODE_OPTIONS: `-r ${fixturesPath}/http/clean-command.js`
}
}).toString()
tap.includes(result, 'Branches deleted:')
tap.includes(result, '- https://github.com/wiby-test/partial: wiby-wiby')
tap.includes(result, '- git://github.com/wiby-test/fail: wiby-wiby')
tap.includes(result, '- git+https://github.com/wiby-test/pass: wiby-wiby')
tap.includes(result, '- https://github.com/wiby-test/partial: wiby-running-unit-tests')
tap.includes(result, '- git://github.com/wiby-test/fail: wiby-running-unit-tests')
tap.includes(result, '- git+https://github.com/wiby-test/pass: wiby-running-unit-tests')
})

tap.test('should delete test branch in the test module at dependent URI', async (tap) => {
const result = childProcess.execSync(`${wibyCommand} clean --dependent="https://github.com/wiby-test/fakeRepo"`, {
cwd: cwd,
env: {
...process.env,
NODE_OPTIONS: `-r ${fixturesPath}/http/clean-command.js`
}
}).toString()
tap.includes(result, 'Branches deleted:')
tap.includes(result, '- https://github.com/wiby-test/fakeRepo: wiby-wiby')
tap.includes(result, '- https://github.com/wiby-test/fakeRepo: wiby-running-unit-tests')
})

tap.test('should delete all wiby-* branches in all configured test modules', async (tap) => {
const result = childProcess.execSync(`${wibyCommand} clean --all`, {
cwd: cwd,
env: {
...process.env,
NODE_OPTIONS: `-r ${fixturesPath}/http/clean-command-all.js`
}
}).toString()
Expand All @@ -48,15 +53,15 @@ tap.test('clean command', async (tap) => {

tap.test('should not delete during dry-run', async (tap) => {
const result = childProcess.execSync(`${wibyCommand} clean --dry-run`, {
cwd: cwd,
env: {
...process.env,
NODE_OPTIONS: `-r ${fixturesPath}/http/clean-command-dry.js`
}
}).toString()

tap.includes(result, 'Branches to be deleted:')
tap.includes(result, '- https://github.com/wiby-test/partial: wiby-wiby')
tap.includes(result, '- git://github.com/wiby-test/fail: wiby-wiby')
tap.includes(result, '- git+https://github.com/wiby-test/pass: wiby-wiby')
tap.includes(result, '- https://github.com/wiby-test/partial: wiby-running-unit-tests')
tap.includes(result, '- git://github.com/wiby-test/fail: wiby-running-unit-tests')
tap.includes(result, '- git+https://github.com/wiby-test/pass: wiby-running-unit-tests')
})
})
21 changes: 13 additions & 8 deletions test/cli/result.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@ const childProcess = require('child_process')
const path = require('path')
const fs = require('fs')

const cwd = path.join(__dirname, '..', '..')
const wibyCommand = path.join(cwd, 'bin', 'wiby')
const gitFixture = require('../fixtures/git')

const wibyCommand = path.join(__dirname, '..', '..', 'bin', 'wiby')
const fixturesPath = path.resolve(path.join(__dirname, '..', 'fixtures'))

const PENDING_RESULT_EXIT_CODE = 64

tap.test('result command', async (tap) => {
tap.beforeEach(async () => {
gitFixture.init()
})

tap.test('result command should fail when config and dependent provided', async (tap) => {
try {
childProcess.execSync(`${wibyCommand} result --config=.wiby.json --dependent="https://github.com/wiby-test/fakeRepo"`, { cwd: cwd }).toString()
childProcess.execSync(`${wibyCommand} result --config=.wiby.json --dependent="https://github.com/wiby-test/fakeRepo"`).toString()
tap.fail()
} catch (err) {
tap.equal(true, err.message.includes('Arguments dependent and config are mutually exclusive'))
Expand All @@ -30,8 +35,8 @@ tap.test('result command', async (tap) => {

try {
childProcess.execSync(`${wibyCommand} result --dependent="https://github.com/wiby-test/fakeRepo"`, {
cwd: cwd,
env: {
...process.env,
NODE_OPTIONS: `-r ${fixturesPath}/http/result-command-positive.js`
}
})
Expand All @@ -52,8 +57,8 @@ tap.test('result command', async (tap) => {

try {
childProcess.execSync(`${wibyCommand} result`, {
cwd: cwd,
env: {
...process.env,
NODE_OPTIONS: `-r ${fixturesPath}/http/result-command-positive.js`
}
})
Expand All @@ -65,7 +70,7 @@ tap.test('result command', async (tap) => {
}
})

tap.test('result command handles empty response from github.getChecks()', tap => {
tap.test('result command handles empty response from github.getChecks()', (tap) => {
const expected = fs.readFileSync(
path.join(__dirname, '..', 'fixtures', 'expected-outputs', 'result', 'result-output-single-dependant.md'),
'utf-8'
Expand All @@ -74,8 +79,8 @@ tap.test('result command', async (tap) => {

try {
childProcess.execSync(`${wibyCommand} result --dependent="https://github.com/wiby-test/fakeRepo"`, {
cwd: cwd,
env: {
...process.env,
NODE_OPTIONS: `-r ${fixturesPath}/http/result-command-empty-branch-checks.js`
}
})
Expand All @@ -98,8 +103,8 @@ tap.test('result command', async (tap) => {

try {
childProcess.execSync(`${wibyCommand} result --dependent="https://github.com/wiby-test/fakeRepo"`, {
cwd: cwd,
env: {
...process.env,
NODE_OPTIONS: `-r ${fixturesPath}/http/result-command-positive-checks-failed.js`
}
})
Expand Down
Loading

0 comments on commit 3986b2f

Please sign in to comment.