Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcf039fd

Browse files
committed
feat: retrieve gitHead from git tag if it's missing from the npm metadata
1 parent4cd5cd7 commitcf039fd

File tree

8 files changed

+253
-1
lines changed

8 files changed

+253
-1
lines changed

‎lib/get-last-release.js‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const npmConf = require('npm-conf');
44
constRegClient=require('npm-registry-client');
55
constgetClientConfig=require('./get-client-config');
66
constgetRegistry=require('./get-registry');
7+
constgetVersionHead=require('./get-version-head');
78

89
module.exports=async({publishConfig, name},logger)=>{
910
constconfig=npmConf();
@@ -30,7 +31,9 @@ module.exports = async ({publishConfig, name}, logger) => {
3031
version=distTags.latest;
3132
logger.log('Found version %s of package %s with dist-tag %s',version,name,'latest');
3233
}
33-
return{version,gitHead:data.versions[version].gitHead};
34+
// Due to npm/read-package-json#77 the gitHead is missing for some packages
35+
// In such case attempt to retrieve the gitHead based on a git tag named after the version
36+
return{version,gitHead:data.versions[version].gitHead||(awaitgetVersionHead(version))};
3437
}catch(err){
3538
if(err.statusCode===404||/notfound/i.test(err.message)){
3639
logger.log('No version found of package %s found on %s',name,registry);

‎lib/get-version-head.js‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
constdebug=require('debug')('semantic-release:npm');
2+
const{gitTagHead, unshallow}=require('./git');
3+
4+
module.exports=asyncversion=>{
5+
lettagHead=(awaitgitTagHead(`v${version}`))||(awaitgitTagHead(version));
6+
7+
// Check if tagHead is found
8+
if(tagHead){
9+
debug('Use tagHead: %s',tagHead);
10+
returntagHead;
11+
}
12+
awaitunshallow();
13+
14+
// Check if tagHead is found
15+
tagHead=(awaitgitTagHead(`v${version}`))||(awaitgitTagHead(version));
16+
if(tagHead){
17+
debug('Use tagHead: %s',tagHead);
18+
returntagHead;
19+
}
20+
};

‎lib/git.js‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
constexeca=require('execa');
2+
constdebug=require('debug')('semantic-release:npm');
3+
4+
/**
5+
* Get the commit sha for a given tag.
6+
*
7+
*@param {string} tagName Tag name for which to retrieve the commit sha.
8+
*
9+
*@return {string} The commit sha of the tag in parameter or `null`.
10+
*/
11+
asyncfunctiongitTagHead(tagName){
12+
try{
13+
returnawaitexeca.stdout('git',['rev-list','-1',tagName]);
14+
}catch(err){
15+
debug(err);
16+
returnnull;
17+
}
18+
}
19+
20+
/**
21+
* Unshallow the git repository (retriving every commits and tags).
22+
*/
23+
asyncfunctionunshallow(){
24+
awaitexeca('git',['fetch','--unshallow','--tags'],{reject:false});
25+
}
26+
27+
module.exports={gitTagHead, unshallow};

‎package.json‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
],
1818
"dependencies": {
1919
"@semantic-release/error":"^2.1.0",
20+
"debug":"^3.1.0",
2021
"execa":"^0.8.0",
2122
"fs-extra":"^5.0.0",
2223
"lodash":"^4.17.4",
@@ -36,6 +37,7 @@
3637
"dockerode":"^2.5.3",
3738
"eslint-config-prettier":"^2.5.0",
3839
"eslint-plugin-prettier":"^2.3.0",
40+
"file-url":"^2.0.2",
3941
"get-stream":"^3.0.0",
4042
"got":"^8.0.0",
4143
"nock":"^9.1.0",

‎test/get-version-head.test.js‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
importtestfrom'ava';
2+
importgetVersionHeadfrom'../lib/get-version-head';
3+
import{gitRepo,gitCommit,gitTagVersion,gitShallowClone}from'./helpers/git-utils';
4+
5+
// Save the current working diretory
6+
constcwd=process.cwd();
7+
8+
test.afterEach.always(()=>{
9+
// Restore the current working directory
10+
process.chdir(cwd);
11+
});
12+
13+
test.serial('Get the commit sha for corresponding the version',asynct=>{
14+
// Create a git repository, set the current working directory at the root of the repo
15+
awaitgitRepo();
16+
// Add commits to the master branch
17+
constcommit=awaitgitCommit('First');
18+
// Create the tag corresponding to version 1.0.0
19+
awaitgitTagVersion('1.0.0');
20+
21+
t.is((awaitgetVersionHead('1.0.0')).substring(0,7),commit.hash);
22+
});
23+
24+
test.serial('Get the commit sha for corresponding the version (starting with v)',asynct=>{
25+
// Create a git repository, set the current working directory at the root of the repo
26+
awaitgitRepo();
27+
// Add commits to the master branch
28+
constcommit=awaitgitCommit('First');
29+
// Create the tag corresponding to version 1.0.0
30+
awaitgitTagVersion('v1.0.0');
31+
32+
t.is((awaitgetVersionHead('1.0.0')).substring(0,7),commit.hash);
33+
});
34+
35+
test.serial('Get the commit sha for corresponding the version on a shallow repository',asynct=>{
36+
// Create a git repository, set the current working directory at the root of the repo
37+
constrepo=awaitgitRepo();
38+
// Add commits to the master branch
39+
constcommit=awaitgitCommit('First');
40+
// Create the tag corresponding to version 1.0.0
41+
awaitgitTagVersion('1.0.0');
42+
// Add additionnal commits
43+
awaitgitCommit('Second');
44+
awaitgitCommit('Third');
45+
// Create a shallow clone with only 1 commit
46+
awaitgitShallowClone(repo);
47+
48+
t.is((awaitgetVersionHead('1.0.0')).substring(0,7),commit.hash);
49+
});

‎test/git.test.js‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
importtestfrom'ava';
2+
import{gitTagHead,unshallow}from'../lib/git';
3+
import{gitRepo,gitCommit,gitTagVersion,gitShallowClone,gitLog}from'./helpers/git-utils';
4+
5+
// Save the current working diretory
6+
constcwd=process.cwd();
7+
8+
test.afterEach.always(()=>{
9+
// Restore the current working directory
10+
process.chdir(cwd);
11+
});
12+
13+
test.serial('Get the commit sha for a given tag or "null" if the tag does not exists',asynct=>{
14+
// Create a git repository, set the current working directory at the root of the repo
15+
awaitgitRepo();
16+
// Add commits to the master branch
17+
constcommit=awaitgitCommit('First');
18+
// Create the tag corresponding to version 1.0.0
19+
awaitgitTagVersion('v1.0.0');
20+
21+
t.is((awaitgitTagHead('v1.0.0')).substring(0,7),commit.hash);
22+
t.falsy(awaitgitTagHead('missing_tag'));
23+
});
24+
25+
test.serial('Unshallow repository',asynct=>{
26+
// Create a git repository, set the current working directory at the root of the repo
27+
constrepo=awaitgitRepo();
28+
// Add commits to the master branch
29+
awaitgitCommit('First');
30+
awaitgitCommit('Second');
31+
// Create a shallow clone with only 1 commit
32+
awaitgitShallowClone(repo);
33+
34+
// Verify the shallow clone contains only one commit
35+
t.is((awaitgitLog()).length,1);
36+
37+
awaitunshallow();
38+
39+
// Verify the shallow clone contains all the commits
40+
t.is((awaitgitLog()).length,2);
41+
});
42+
43+
test.serial('Do not throw error when unshallow a complete repository',asynct=>{
44+
// Create a git repository, set the current working directory at the root of the repo
45+
awaitgitRepo();
46+
// Add commits to the master branch
47+
awaitgitCommit('First');
48+
awaitt.notThrows(unshallow());
49+
});

‎test/helpers/git-utils.js‎

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
importtempyfrom'tempy';
2+
importfileUrlfrom'file-url';
3+
importexecafrom'execa';
4+
5+
/**
6+
* Create a temporary git repository and change the current working directory to the repository root.
7+
*
8+
*@return {string} The path of the repository.
9+
*/
10+
exportasyncfunctiongitRepo(){
11+
constdir=tempy.directory();
12+
13+
process.chdir(dir);
14+
awaitexeca('git',['init']);
15+
awaitgitCheckout('master');
16+
returndir;
17+
}
18+
19+
/**
20+
* Checkout a branch on the current git repository.
21+
*
22+
*@param {string} branch Branch name.
23+
*@param {boolean} create `true` to create the branche ans switch, `false` to only switch.
24+
*/
25+
exportasyncfunctiongitCheckout(branch,create=true){
26+
awaitexeca('git',create ?['checkout','-b',branch] :['checkout',branch]);
27+
}
28+
29+
/**
30+
* Create commit on the current git repository.
31+
*
32+
*@param {String} message commit message.
33+
*
34+
*@returns {Commit} The created commits.
35+
*/
36+
exportasyncfunctiongitCommit(message){
37+
const{stdout}=awaitexeca('git',['commit','-m',message,'--allow-empty','--no-gpg-sign']);
38+
const[,branch,hash]=/^\[(\w+)\(?.*?\)?(\w+)\].+(?:\n|$)/.exec(stdout);
39+
return{branch, hash, message};
40+
}
41+
42+
/**
43+
* Create a tag on the head commit in the current git repository.
44+
*
45+
*@param {string} tagName The tag name to create.
46+
*@param {string} [sha] The commit on which to create the tag. If undefined the tag is created on the last commit.
47+
*
48+
*@return {string} The commit sha of the created tag.
49+
*/
50+
exportasyncfunctiongitTagVersion(tagName,sha){
51+
awaitexeca('git',sha ?['tag','-f',tagName,sha] :['tag',tagName]);
52+
return(awaitexeca('git',['rev-list','-1','--tags',tagName])).stdout;
53+
}
54+
55+
/**
56+
* Create a shallow clone of a git repository and change the current working directory to the cloned repository root.
57+
* The shallow will contain a limited number of commit and no tags.
58+
*
59+
*@param {string} origin The path of the repository to clone.
60+
*@param {number} [depth=1] The number of commit to clone.
61+
*@return {string} The path of the cloned repository.
62+
*/
63+
exportasyncfunctiongitShallowClone(origin,branch='master',depth=1){
64+
constdir=tempy.directory();
65+
66+
process.chdir(dir);
67+
awaitexeca('git',['clone','--no-hardlinks','--no-tags','-b',branch,'--depth',depth,fileUrl(origin),dir]);
68+
returndir;
69+
}
70+
71+
/**
72+
*@return {Array<string>} The list of commit sha from the current git repository.
73+
*/
74+
exportasyncfunctiongitLog(){
75+
return(awaitexeca('git',['log','--format=format:%H'])).stdout.split('\n').filter(sha=>Boolean(sha));
76+
}
77+
78+
/**
79+
* Pack heads and tags of the current git repository.
80+
*/
81+
exportasyncfunctiongitPackRefs(){
82+
awaitexeca('git',['pack-refs','--all']);
83+
}

‎test/integration.test.js‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import tempy from 'tempy';
66
importclearModulefrom'clear-module';
77
importSemanticReleaseErrorfrom'@semantic-release/error';
88
importnpmRegistryfrom'./helpers/npm-registry';
9+
import{gitRepo,gitCommit,gitTagVersion,gitPackRefs}from'./helpers/git-utils';
910

1011
// Save the current process.env
1112
constenvBackup=Object.assign({},process.env);
@@ -364,3 +365,21 @@ test.serial('Verify token and set up auth only on the fist call', async t => {
364365
nextRelease=awaitt.context.m.getLastRelease({},{options:{},logger:t.context.logger});
365366
t.is(nextRelease.version,'1.0.0');
366367
});
368+
369+
test.serial('Retrieve gitHead with tag for package released on a git repository with packed-refs',asynct=>{
370+
Object.assign(process.env,npmRegistry.authEnv);
371+
constpkg={name:'test-packed-ref',version:'0.0.0-dev',publishConfig:{registry:npmRegistry.url}};
372+
373+
// Create a git repository, set the current working directory at the root of the repo
374+
awaitgitRepo();
375+
awaitoutputJson('./package.json',pkg);
376+
// Add commits to the master branch
377+
constcommit=awaitgitCommit('First');
378+
awaitgitPackRefs();
379+
// Create the tag corresponding to version 1.0.0
380+
awaitgitTagVersion('1.0.0');
381+
awaitt.context.m.publish({},{logger:t.context.logger,nextRelease:{version:'1.0.0'}});
382+
383+
constnextRelease=awaitt.context.m.getLastRelease({},{options:{},logger:t.context.logger});
384+
t.is(nextRelease.gitHead.substring(0,7),commit.hash);
385+
});

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp