Skip to content

Commit

Permalink
Add logic for pushing to forks on "pull_request" events
Browse files Browse the repository at this point in the history
Only works partly due to GitHub's token scopes. See #13
  • Loading branch information
samuelmeuli committed Feb 22, 2020
1 parent 168fd66 commit 103a9e2
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 31 deletions.
56 changes: 31 additions & 25 deletions src/git.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,33 @@
const { log, run } = require("./utils/action");

/**
* Switches the Git branch
* @param {string} branchName - Name of the branch which should be switched to
* Fetches and checks out the remote Git branch (if it exists, the fork repository will be used)
* @param {import('./github/context').GithubContext} context - Information about the GitHub
*/
function checkOutBranch(branchName) {
log(`Checking out the "${branchName}" branch`);
run(`git checkout ${branchName}`);
function checkOutRemoteBranch(context) {
if (context.repository.hasFork) {
// Fork: Add fork repo as remote
log(`Adding "${context.repository.forkName}" fork as remote with Git`);
run(
`git remote add fork https://${context.actor}:${context.token}@github.com/${context.repository.forkName}.git`,
);
} else {
// No fork: Update remote URL to include auth information (so auto-fixes can be pushed)
log(`Adding auth information to Git remote URL`);
run(
`git remote set-url origin https://${context.actor}:${context.token}@github.com/${context.repository.repoName}.git`,
);
}

const remote = context.repository.hasFork ? "fork" : "origin";

// Fetch remote branch
log(`Fetching remote branch "${context.branch}"`);
run(`git fetch --no-tags --depth=1 ${remote} ${context.branch}`);

// Switch to remote branch
log(`Switching to the "${context.branch}" branch`);
run(`git switch --force-create ${context.branch} --track ${remote}/${context.branch}`);
}

/**
Expand All @@ -18,14 +39,6 @@ function commitChanges(message) {
run(`git commit -am "${message}"`);
}

/**
* Fetches all remote Git branches
*/
function fetchBranches() {
log(`Fetching all remote Git branches`);
run("git fetch --no-tags --prune --depth=1 origin +refs/heads/*:refs/remotes/origin/*");
}

/**
* Returns the SHA of the head commit
* @returns {string} - Head SHA
Expand All @@ -47,17 +60,11 @@ function hasChanges() {
}

/**
* Pushes all changes to the GitHub repository
* @param {import('./github/context').GithubContext} context - Information about the GitHub
* repository and action trigger event
* Pushes all changes to the remote repository
*/
function pushChanges(context) {
const remote = `https://${context.actor}:${context.token}@github.com/${context.repository.repoName}.git`;
const localBranch = "HEAD";
const remoteBranch = context.branch;

log(`Pushing changes to ${remote}`);
run(`git push "${remote}" ${localBranch}:${remoteBranch} --follow-tags`);
function pushChanges() {
log("Pushing changes with Git");
run("git push");
}

/**
Expand All @@ -72,9 +79,8 @@ function setUserInfo(name, email) {
}

module.exports = {
checkOutBranch,
checkOutRemoteBranch,
commitChanges,
fetchBranches,
getHeadSha,
hasChanges,
pushChanges,
Expand Down
17 changes: 11 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,16 @@ async function runAction() {
git.setUserInfo(GIT_NAME, GIT_EMAIL);
}
if (context.eventName === "pull_request") {
// Fetch and check out PR branch. This is required because for "pull_request" events, the
// Checkout Action (https://github.com/actions/checkout) checks out the PR's test merge commit
// in detached head state
git.fetchBranches();
git.checkOutBranch(context.branch);
// Fetch and check out PR branch:
// - "push" event: Already on correct branch
// - "pull_request" event on origin, for code on origin: The Checkout Action
// (https://github.com/actions/checkout) checks out the PR's test merge commit instead of the
// PR branch. Git is therefore in detached head state. To be able to push changes, the branch
// needs to be fetched and checked out first
// - "pull_request" event on origin, for code on fork: Same as above, but the repo/branch where
// changes need to be pushed is not yet available. The fork needs to be added as a Git remote
// first
git.checkOutRemoteBranch(context);
}

const checks = [];
Expand Down Expand Up @@ -71,7 +76,7 @@ async function runAction() {
// Commit and push auto-fix changes
if (git.hasChanges()) {
git.commitChanges(commitMsg.replace(/\${linter}/g, linter.name));
git.pushChanges(context);
git.pushChanges();
}
}

Expand Down

0 comments on commit 103a9e2

Please sign in to comment.