Skip to content

Commit

Permalink
feat: use one note reference per tag to prevent conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
KillianHmyd committed Aug 10, 2022
1 parent 3bbf08c commit 37ad7d3
Show file tree
Hide file tree
Showing 6 changed files with 5,894 additions and 6,089 deletions.
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ async function run(context, plugins) {
} else {
await addNote({channels: [...currentRelease.channels, nextRelease.channel]}, nextRelease.gitHead, {cwd, env});
await push(options.repositoryUrl, {cwd, env});
await pushNotes(options.repositoryUrl, {cwd, env});
await pushNotes(options.repositoryUrl, nextRelease.gitHead, {cwd, env});
logger.success(
`Add ${nextRelease.channel ? `channel ${nextRelease.channel}` : 'default channel'} to tag ${
nextRelease.gitTag
Expand Down Expand Up @@ -199,7 +199,7 @@ async function run(context, plugins) {
await tag(nextRelease.gitTag, nextRelease.gitHead, {cwd, env});
await addNote({channels: [nextRelease.channel]}, nextRelease.gitHead, {cwd, env});
await push(options.repositoryUrl, {cwd, env});
await pushNotes(options.repositoryUrl, {cwd, env});
await pushNotes(options.repositoryUrl, nextRelease.gitHead, {cwd, env});
logger.success(`Created tag ${nextRelease.gitTag}`);
}

Expand Down
11 changes: 9 additions & 2 deletions lib/branches/get-tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const {template, escapeRegExp} = require('lodash');
const semver = require('semver');
const pReduce = require('p-reduce');
const debug = require('debug')('semantic-release:get-tags');
const {getTags, getNote} = require('../../lib/git');
const {getTags, getNote, getTagRef} = require('../../lib/git');

module.exports = async ({cwd, env, options: {tagFormat}}, branches) => {
// Generate a regex to parse tags formatted with `tagFormat`
Expand All @@ -19,7 +19,14 @@ module.exports = async ({cwd, env, options: {tagFormat}}, branches) => {
async (branchTags, tag) => {
const [, version] = tag.match(tagRegexp) || [];
return version && semver.valid(semver.clean(version))
? [...branchTags, {gitTag: tag, version, channels: (await getNote(tag, {cwd, env})).channels || [null]}]
? [
...branchTags,
{
gitTag: tag,
version,
channels: (await getNote(await getTagRef(tag, {cwd, env}), {cwd, env})).channels || [null],
},
]
: branchTags;
},
[]
Expand Down
49 changes: 38 additions & 11 deletions lib/git.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const gitLogParser = require('git-log-parser');
const getStream = require('get-stream');
const execa = require('execa');
const debug = require('debug')('semantic-release:git');
const {merge} = require('lodash');
const {GIT_NOTE_REF} = require('./definitions/constants');

Object.assign(gitLogParser.fields, {hash: 'H', message: 'B', gitTags: 'd', committerDate: {key: 'ci', type: Date}});
Expand Down Expand Up @@ -139,13 +140,9 @@ async function fetch(repositoryUrl, branch, ciBranch, execaOptions) {
*/
async function fetchNotes(repositoryUrl, execaOptions) {
try {
await execa(
'git',
['fetch', '--unshallow', repositoryUrl, `+refs/notes/${GIT_NOTE_REF}:refs/notes/${GIT_NOTE_REF}`],
execaOptions
);
} catch {
await execa('git', ['fetch', repositoryUrl, `+refs/notes/${GIT_NOTE_REF}:refs/notes/${GIT_NOTE_REF}`], {
await execa('git', ['fetch', '--unshallow', repositoryUrl, `+refs/notes/*:refs/notes/*`], execaOptions);
} catch (_) {
await execa('git', ['fetch', repositoryUrl, `+refs/notes/*:refs/notes/*`], {
...execaOptions,
reject: false,
});
Expand Down Expand Up @@ -244,8 +241,8 @@ async function push(repositoryUrl, execaOptions) {
*
* @throws {Error} if the push failed.
*/
async function pushNotes(repositoryUrl, execaOptions) {
await execa('git', ['push', repositoryUrl, `refs/notes/${GIT_NOTE_REF}`], execaOptions);
async function pushNotes(repositoryUrl, ref, execaOptions) {
await execa('git', ['push', repositoryUrl, `refs/notes/${GIT_NOTE_REF}-${ref}`], execaOptions);
}

/**
Expand Down Expand Up @@ -306,7 +303,22 @@ async function isBranchUpToDate(repositoryUrl, branch, execaOptions) {
*/
async function getNote(ref, execaOptions) {
try {
return JSON.parse((await execa('git', ['notes', '--ref', GIT_NOTE_REF, 'show', ref], execaOptions)).stdout);
return merge(
JSON.parse(
// Used for retro-compatibility
(
await execa('git', ['notes', '--ref', GIT_NOTE_REF, 'show', ref], execaOptions).catch((error) => {
if (error.exitCode === 1) {
return '{}';
}

debug(error);
throw error;
})
).stdout || '{}'
),
JSON.parse((await execa('git', ['notes', '--ref', `${GIT_NOTE_REF}-${ref}`, 'show', ref], execaOptions)).stdout)
);
} catch (error) {
if (error.exitCode === 1) {
return {};
Expand All @@ -325,11 +337,26 @@ async function getNote(ref, execaOptions) {
* @param {Object} [execaOpts] Options to pass to `execa`.
*/
async function addNote(note, ref, execaOptions) {
await execa('git', ['notes', '--ref', GIT_NOTE_REF, 'add', '-f', '-m', JSON.stringify(note), ref], execaOptions);
await execa(
'git',
['notes', '--ref', `${GIT_NOTE_REF}-${ref}`, 'add', '-f', '-m', JSON.stringify(note), ref],
execaOptions
);
}

/**
* Get the reference of a tag
*
* @param {String} tag The tag name to get the reference of.
* @param {Object} [execaOpts] Options to pass to `execa`.
**/
async function getTagRef(tag, execaOptions) {
return (await execa('git', ['show-ref', tag, '--hash'], execaOptions)).stdout;
}

module.exports = {
getTagHead,
getTagRef,
getTags,
getCommits,
getBranches,
Expand Down

0 comments on commit 37ad7d3

Please sign in to comment.