Skip to content

Commit

Permalink
Merge pull request #28 from s0/skip-empty-commits
Browse files Browse the repository at this point in the history
Allow skipping of empty commits
  • Loading branch information
s0 authored Sep 19, 2020
2 parents ff973c4 + 7fed164 commit 43ac335
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 9 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ All configuration options are passed in via `env`, as environment variables.
| `KNOWN_HOSTS_FILE` | Path to a file in the repository that contains the known SSH fingerprints for the target host. | When the target host is not github.com |
| `GITHUB_TOKEN` | Should always be equal to `${{ secrets.GITHUB_TOKEN }}` | When `REPO = self` |
| `SQUASH_HISTORY` | If set to `true`, all previous commits on the target branch will be discarded. For example, if you are deploying a static site with lots of binary artifacts, this can help the repository becoming overly bloated. | No |
| `SKIP_EMPTY_COMMITS` | If set to `true`, commits will only be pushed if the contents of the target branch will be changed as a result. This is useful if, for example, you'd like to easily track which upstream changes result in changes to your target branch. | No |
| `MESSAGE` | A custom template to use as the commit message pushed to the target branch. See [custom commit messages](#custom-commit-messages). | No |
| `TAG` | A string following the [git-check-ref-format](https://git-scm.com/docs/git-check-ref-format) that tags the commit with a lightweight git-tag. | No |

Expand Down
45 changes: 39 additions & 6 deletions action/dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8016,6 +8016,7 @@ var config = (function () {
var branch = ENV.BRANCH;
var folder = ENV.FOLDER;
var squashHistory = ENV.SQUASH_HISTORY === 'true';
var skipEmptyCommits = ENV.SKIP_EMPTY_COMMITS === 'true';
var message = ENV.MESSAGE || DEFAULT_MESSAGE;
var tag = ENV.TAG;
// Determine the type of URL
Expand All @@ -8030,6 +8031,7 @@ var config = (function () {
branch: branch,
folder: folder,
squashHistory: squashHistory,
skipEmptyCommits: skipEmptyCommits,
mode: 'self',
message: message,
tag: tag,
Expand All @@ -8045,6 +8047,7 @@ var config = (function () {
branch: branch,
folder: folder,
squashHistory: squashHistory,
skipEmptyCommits: skipEmptyCommits,
mode: 'ssh',
parsedUrl: parsedUrl,
privateKey: ENV.SSH_PRIVATE_KEY,
Expand Down Expand Up @@ -8085,7 +8088,7 @@ var writeToProcess = function (command, args, opts) { return new Promise(functio
});
}); };
(function () { return __awaiter(void 0, void 0, void 0, function () {
var TMP_PATH, REPO_TEMP, SSH_AUTH_SOCK, event, _a, _b, name, email, tag, getGitInformation, gitInfo, env, known_hosts, sshAgentMatch, _c, _d, branchCheck, folder, message, forceArg, tagsArg, push;
var TMP_PATH, REPO_TEMP, SSH_AUTH_SOCK, event, _a, _b, name, email, tag, getGitInformation, gitInfo, env, known_hosts, sshAgentMatch, _c, _d, branchCheck, folder, message, head, currentCommit, previousCommit, forceArg, tagsArg, push;
var _e, _f;
return __generator(this, function (_g) {
switch (_g.label) {
Expand Down Expand Up @@ -8313,21 +8316,51 @@ var writeToProcess = function (command, args, opts) { return new Promise(functio
_g.sent();
_g.label = 30;
case 30:
if (!config.skipEmptyCommits) return [3 /*break*/, 34];
console.log("##[info] Checking whether contents have changed before pushing");
return [4 /*yield*/, isomorphic_git_1.default.resolveRef({
fs: fs,
dir: REPO_TEMP,
ref: 'HEAD'
})];
case 31:
head = _g.sent();
return [4 /*yield*/, isomorphic_git_1.default.readCommit({
fs: fs,
dir: REPO_TEMP,
oid: head,
})];
case 32:
currentCommit = _g.sent();
if (!(currentCommit.commit.parent.length === 1)) return [3 /*break*/, 34];
return [4 /*yield*/, isomorphic_git_1.default.readCommit({
fs: fs,
dir: REPO_TEMP,
oid: currentCommit.commit.parent[0],
})];
case 33:
previousCommit = _g.sent();
if (currentCommit.commit.tree === previousCommit.commit.tree) {
console.log("##[info] Contents of target repo unchanged, exiting.");
return [2 /*return*/];
}
_g.label = 34;
case 34:
console.log("##[info] Pushing");
forceArg = config.squashHistory ? '-f' : '';
tagsArg = tag ? '--tags' : '';
return [4 /*yield*/, exec("git push " + forceArg + " origin \"" + config.branch + "\" " + tagsArg, { env: env, cwd: REPO_TEMP })];
case 31:
case 35:
push = _g.sent();
console.log(push.stdout);
console.log("##[info] Deployment Successful");
if (!(config.mode === 'ssh')) return [3 /*break*/, 33];
if (!(config.mode === 'ssh')) return [3 /*break*/, 37];
console.log("##[info] Killing ssh-agent");
return [4 /*yield*/, exec("ssh-agent -k", { env: env })];
case 32:
case 36:
_g.sent();
_g.label = 33;
case 33: return [2 /*return*/];
_g.label = 37;
case 37: return [2 /*return*/];
}
});
}); })().catch(function (err) {
Expand Down
37 changes: 37 additions & 0 deletions action/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ export interface EnvironmentVariables {
* Set to "true" to clear all of the history of the target branch and force push
*/
SQUASH_HISTORY?: string;
/**
* Set to "true" to avoid pushing commits that don't change any files.
*
* This is useful for example when you want to be able to easily identify
* which upstream changes resulted in changes to this repository.
*/
SKIP_EMPTY_COMMITS?: string;
/**
* An optional template string to use for the commit message,
* if not provided, a default template is used.
Expand Down Expand Up @@ -119,6 +126,7 @@ interface BaseConfig {
folder: string;
repo: string;
squashHistory: boolean;
skipEmptyCommits: boolean;
message: string;
tag?: string;
}
Expand Down Expand Up @@ -158,6 +166,7 @@ const config: Config = (() => {
const branch = ENV.BRANCH;
const folder = ENV.FOLDER;
const squashHistory = ENV.SQUASH_HISTORY === 'true';
const skipEmptyCommits = ENV.SKIP_EMPTY_COMMITS === 'true';
const message = ENV.MESSAGE || DEFAULT_MESSAGE;
const tag = ENV.TAG;

Expand All @@ -173,6 +182,7 @@ const config: Config = (() => {
branch,
folder,
squashHistory,
skipEmptyCommits,
mode: 'self',
message,
tag,
Expand All @@ -189,6 +199,7 @@ const config: Config = (() => {
branch,
folder,
squashHistory,
skipEmptyCommits,
mode: 'ssh',
parsedUrl,
privateKey: ENV.SSH_PRIVATE_KEY,
Expand Down Expand Up @@ -415,6 +426,32 @@ const writeToProcess = (command: string, args: string[], opts: { env: { [id: str
ref: tag,
});
}
if (config.skipEmptyCommits) {
console.log(`##[info] Checking whether contents have changed before pushing`);
// Before we push, check whether it changed the tree,
// and avoid pushing if not
const head = await git.resolveRef({
fs,
dir: REPO_TEMP,
ref: 'HEAD'
});
const currentCommit = await git.readCommit({
fs,
dir: REPO_TEMP,
oid: head,
});
if (currentCommit.commit.parent.length === 1) {
const previousCommit = await git.readCommit({
fs,
dir: REPO_TEMP,
oid: currentCommit.commit.parent[0],
});
if (currentCommit.commit.tree === previousCommit.commit.tree) {
console.log(`##[info] Contents of target repo unchanged, exiting.`);
return;
}
}
}
console.log(`##[info] Pushing`);
const forceArg = config.squashHistory ? '-f' : '';
const tagsArg = tag ? '--tags' : '';
Expand Down
2 changes: 1 addition & 1 deletion action/test/jest-global-setup-hooks.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
jest.setTimeout(15000);
jest.setTimeout(1000 * 60 * 60);
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Skip empty commits 1`] = `
"msg:Update branch-a to output generated at <sha1>
tree:b60735c9b4d9728b47c0f2752bb973cd6f3d9d80
author:s0 <[email protected]>
msg:Update branch-a to output generated at <sha2>
tree:8bf87c66655949e66937b11593cc4ae732d1f610
author:s0 <[email protected]>"
`;
2 changes: 0 additions & 2 deletions action/test/specs/ssh-github.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ const DATA_DIR = path.join(util.DATA_DIR, 'ssh-no-branch-github');

it('Deploy to an existing branch on GitHub', async () => {

jest.setTimeout(1000 * 60 * 60);

// Create empty repo
await util.mkdir(REPO_DIR);
await util.execWithOutput('git init --bare', { cwd: REPO_DIR });
Expand Down
82 changes: 82 additions & 0 deletions action/test/specs/ssh-skip-empty-commits.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import * as path from 'path';

import * as util from '../util';

const REPO_DIR = path.join(util.REPOS_DIR, 'ssh-skip-empty-commits.git');
const DATA_DIR = path.join(util.DATA_DIR, 'ssh-skip-empty-commits');

it('Skip empty commits', async () => {

// Create empty repo
await util.mkdir(REPO_DIR);
await util.execWithOutput('git init --bare', { cwd: REPO_DIR });

// Create dummy data
await util.mkdir(DATA_DIR);
await util.mkdir(path.join(DATA_DIR, 'dummy'));
await util.writeFile(path.join(DATA_DIR, 'dummy', 'baz'), 'foobar');
await util.writeFile(path.join(DATA_DIR, 'dummy', '.bat'), 'foobar');

// Run Action
await util.runWithGithubEnv(
path.basename(__filename),
{
REPO: 'ssh://git@git-ssh/git-server/repos/ssh-skip-empty-commits.git',
BRANCH: 'branch-a',
FOLDER: DATA_DIR,
SSH_PRIVATE_KEY: (await util.readFile(util.SSH_PRIVATE_KEY)).toString(),
KNOWN_HOSTS_FILE: util.KNOWN_HOSTS,
SKIP_EMPTY_COMMITS: 'true',
},
's0/test',
{},
's0',
);
const fullSha1 = await util.getFullRepoSha();
// Change files and run action again
await util.writeFile(path.join(DATA_DIR, 'dummy', 'bat'), 'foobar');
await util.runWithGithubEnv(
path.basename(__filename),
{
REPO: 'ssh://git@git-ssh/git-server/repos/ssh-skip-empty-commits.git',
BRANCH: 'branch-a',
FOLDER: DATA_DIR,
SSH_PRIVATE_KEY: (await util.readFile(util.SSH_PRIVATE_KEY)).toString(),
KNOWN_HOSTS_FILE: util.KNOWN_HOSTS,
SKIP_EMPTY_COMMITS: 'true',
},
's0/test',
{},
's0',
);
const fullSha2 = await util.getFullRepoSha();
// Run the action again with no content changes to test skip behaviour
await util.runWithGithubEnv(
path.basename(__filename),
{
REPO: 'ssh://git@git-ssh/git-server/repos/ssh-skip-empty-commits.git',
BRANCH: 'branch-a',
FOLDER: DATA_DIR,
SSH_PRIVATE_KEY: (await util.readFile(util.SSH_PRIVATE_KEY)).toString(),
KNOWN_HOSTS_FILE: util.KNOWN_HOSTS,
SKIP_EMPTY_COMMITS: 'true',
},
's0/test',
{},
's0',
);

// Check that the log of the repo is as expected
// (check tree-hash, commit message, and author)
// TODO: test {msg} placeholder and running action outside of a git repo
let log = (await util.exec(
'git log --pretty="format:msg:%B%ntree:%T%nauthor:%an <%ae>" branch-a',
{
cwd: REPO_DIR
}
)).stdout;
const sha1 = fullSha1.substr(0, 7);
const sha2 = fullSha2.substr(0, 7);
const cleanedLog = log.replace(sha1, '<sha1>').replace(sha2, '<sha2>');
expect(cleanedLog).toMatchSnapshot();
});

0 comments on commit 43ac335

Please sign in to comment.