Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: commit files from assets even if in they are in .gitignore #56

Merged
merged 1 commit into from
Jun 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Each entry in the `assets` `Array` is globbed individually. A [glob](https://git

If a directory is configured, all the files under this directory and its children will be included.

If a file has a match in `.gitignore` it will always be excluded.
**Note**: If a file has a match in `assets` it will be included even if it also has a match in `.gitignore`.

##### `assets` examples

Expand Down
7 changes: 3 additions & 4 deletions lib/git.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,19 @@ const debug = require('debug')('semantic-release:git');
* @return {Array<String>} Array of modified files path.
*/
async function getModifiedFiles() {
return (await execa.stdout('git', ['ls-files', '-m', '-o', '--exclude-standard']))
return (await execa.stdout('git', ['ls-files', '-m', '-o']))
.split('\n')
.map(tag => tag.trim())
.filter(tag => Boolean(tag));
}

/**
* Add a list of file to the Git index.
* If on of the files is present in the .gitignore it will be silently skipped. Other files will still be added.
* Add a list of file to the Git index. `.gitignore` will be ignored.
*
* @param {Array<String>} files Array of files path to add to the index,
*/
async function add(files) {
const shell = await execa('git', ['add', '--ignore-errors'].concat(files), {reject: false});
const shell = await execa('git', ['add', '--force', '--ignore-errors'].concat(files), {reject: false});
debug('add file to git index', shell);
}

Expand Down
7 changes: 4 additions & 3 deletions test/git.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ test.serial('Add file to index', async t => {
await t.deepEqual(await gitStaged(), ['file1.js']);
});

test.serial('Get the modified files, ignoring files in .gitignore but including untracked ones', async t => {
test.serial('Get the modified files, including files in .gitignore but including untracked ones', async t => {
// Create a git repository, set the current working directory at the root of the repo
await gitRepo();
// Create files
Expand All @@ -34,13 +34,14 @@ test.serial('Get the modified files, ignoring files in .gitignore but including
// Add files and commit
await add(['.']);
await commit('Test commit');
// Update file1.js and dir/file2.js
// Update file1.js, dir/file2.js and file3.js
await appendFile('file1.js', 'Test content');
await appendFile('dir/file2.js', 'Test content');
await appendFile('file3.js', 'Test content');
// Add untracked file
await outputFile('file4.js', 'Test content');

await t.deepEqual(await getModifiedFiles(), ['file4.js', 'dir/file2.js', 'file1.js']);
await t.deepEqual((await getModifiedFiles()).sort(), ['file4.js', 'file3.js', 'dir/file2.js', 'file1.js'].sort());
});

test.serial('Returns [] if there is no modified files', async t => {
Expand Down
34 changes: 12 additions & 22 deletions test/prepare.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,13 @@ test.serial('Commit files matching the patterns in "assets"', async t => {
// Verify file2 and file1 have been commited
// file4.js is excluded as no glob matching
// file3.css is ignored due to the negative glob '!dir/*.css'
// file5.js is ignore because it's in the .gitignore
// file5.js is not ignored even if it's in the .gitignore
// file6.js and file7.css are included because dir2 is expanded
t.deepEqual(await gitCommitedFiles(), ['dir/file2.js', 'dir2/file6.js', 'dir2/file7.css', 'file1.js']);
t.deepEqual(t.context.log.args[0], ['Found %d file(s) to commit', 4]);
t.deepEqual(
(await gitCommitedFiles()).sort(),
['dir/file2.js', 'dir2/file6.js', 'dir2/file7.css', 'file1.js', 'file5.js'].sort()
);
t.deepEqual(t.context.log.args[0], ['Found %d file(s) to commit', 5]);
});

test.serial('Commit files matching the patterns in "assets" as Objects', async t => {
Expand All @@ -155,10 +158,13 @@ test.serial('Commit files matching the patterns in "assets" as Objects', async t
// Verify file2 and file1 have been commited
// file4.js is excluded as no glob matching
// file3.css is ignored due to the negative glob '!dir/*.css'
// file5.js is ignore because it's in the .gitignore
// file5.js is not ignored even if it's in the .gitignore
// file6.js and file7.css are included because dir2 is expanded
t.deepEqual(await gitCommitedFiles(), ['dir/file2.js', 'dir2/file6.js', 'dir2/file7.css', 'file1.js']);
t.deepEqual(t.context.log.args[0], ['Found %d file(s) to commit', 4]);
t.deepEqual(
(await gitCommitedFiles()).sort(),
['dir/file2.js', 'dir2/file6.js', 'dir2/file7.css', 'file1.js', 'file5.js'].sort()
);
t.deepEqual(t.context.log.args[0], ['Found %d file(s) to commit', 5]);
});

test.serial('Commit files matching the patterns in "assets" as single glob', async t => {
Expand Down Expand Up @@ -237,19 +243,3 @@ test.serial('Skip commit if there is no files to commit', async t => {
t.deepEqual(t.context.log.args[0], ['Creating tag %s', nextRelease.gitTag]);
t.deepEqual(t.context.log.args[1], ['Prepared Git release: %s', nextRelease.gitTag]);
});

test.serial('Skip commit if all the modified files are in .gitignore', async t => {
const pluginConfig = {assets: 'dist'};
const lastRelease = {};
const nextRelease = {version: '2.0.0', gitTag: 'v2.0.0'};

await outputFile('dist/files1.js', 'Test content');
await outputFile('.gitignore', 'dist/**/*');

await prepare(pluginConfig, {options: t.context.options, lastRelease, nextRelease, logger: t.context.logger});

// Verify the files that have been commited
t.deepEqual(await gitCommitedFiles(), []);
t.deepEqual(t.context.log.args[0], ['Creating tag %s', nextRelease.gitTag]);
t.deepEqual(t.context.log.args[1], ['Prepared Git release: %s', nextRelease.gitTag]);
});