diff --git a/lib/manager/npm/post-update/types.ts b/lib/manager/npm/post-update/types.ts index 035ac3d39d47c23597a4f0f664d2c4a5f8deacef..8b4605f2274cd4a463ed41c93d5ae791cff8093b 100644 --- a/lib/manager/npm/post-update/types.ts +++ b/lib/manager/npm/post-update/types.ts @@ -19,6 +19,7 @@ export interface ArtifactError { export interface UpdatedArtifacts { name: string; contents: string | Buffer; + executable?: boolean; } export interface WriteExistingFilesResult { diff --git a/lib/util/git/index.spec.ts b/lib/util/git/index.spec.ts index d7412b372082832a59a5b28670bf2a0f0f4f94fb..42bae467a5b059b35200ad11e126ae9e0ad659d8 100644 --- a/lib/util/git/index.spec.ts +++ b/lib/util/git/index.spec.ts @@ -412,6 +412,24 @@ describe('util/git/index', () => { expect.objectContaining({ '--no-verify': null }) ); }); + + it('creates file with the executable bit', async () => { + const file = { + name: 'some-executable', + contents: 'some new-contents', + executable: true, + }; + const commit = await git.commitFiles({ + branchName: 'renovate/past_branch', + files: [file], + message: 'Create something', + }); + expect(commit).not.toBeNull(); + + const repo = Git(tmpDir.path); + const result = await repo.raw(['ls-tree', 'HEAD', 'some-executable']); + expect(result).toStartWith('100755'); + }); }); describe('getCommitMessages()', () => { diff --git a/lib/util/git/index.ts b/lib/util/git/index.ts index 3c7610ecb4562b349aaf34c411abbddd3dcc74c3..ebcbcf198124331932ce01e8e0916cfaa94a2d98 100644 --- a/lib/util/git/index.ts +++ b/lib/util/git/index.ts @@ -653,6 +653,11 @@ export interface File { * file contents */ contents: string | Buffer; + + /** + * the executable bit + */ + executable?: boolean; } export type CommitFilesConfig = { @@ -709,10 +714,17 @@ export async function commitFiles({ } else { contents = file.contents; } - await fs.outputFile(join(localDir, fileName), contents); + // some file systems including Windows don't support the mode + // so the index should be manually updated after adding the file + await fs.outputFile(join(localDir, fileName), contents, { + mode: file.executable ? 0o777 : 0o666, + }); } try { await git.add(fileName); + if (file.executable) { + await git.raw(['update-index', '--chmod=+x', fileName]); + } addedModifiedFiles.push(fileName); } catch (err) /* istanbul ignore next */ { if (