Skip to content

Commit

Permalink
✨ Add fork workflow functionality (#135)
Browse files Browse the repository at this point in the history
Implements #133 

Co-authored-by: Maximilian Schiller <schiller@mxis.ch>
  • Loading branch information
xanjohns and BetaHuhn committed Dec 11, 2021
1 parent 996aa41 commit 80e77fd
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 12 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ Here are all the inputs [repo-file-sync-action](https://github.com/BetaHuhn/repo
| `DRY_RUN` | Run everything except that nothing will be pushed | **No** | false |
| `SKIP_CLEANUP` | Skips removing the temporary directory. Useful for debugging | **No** | false |
| `SKIP_PR` | Skips creating a Pull Request and pushes directly to the default branch | **No** | false |
| `FORK` | A Github account username. Changes will be pushed to a fork of target repos on this account. | **No** | false |

### Outputs

Expand Down Expand Up @@ -389,6 +390,21 @@ The above example would result in a commit message that looks something like thi
Change-type: patch
```

### Fork and pull request workflow

If you do not wish to grant this action write access to target repositories, you can specify a bot/user Github acccount that you do have access to with the `FORK` parameter.

A fork of each target repository will be created on this account, and all changes will be pushed to a branch on the fork, instead of upstream. Pull requests will be opened from the forks to target repositories.

Note: while you can open pull requests to target repositories without write access, some features, like applying labels, are not possible.

```yml
uses: BetaHuhn/repo-file-sync-action@v1
with:
GH_PAT: ${{ secrets.GH_PAT }}
FORK: file-sync-bot
```

### Advanced sync config

Here's how I keep common files in sync across my repositories. The main repository [`github-files`](https://github.com/BetaHuhn/github-files) contains all the files I want to sync and the [repo-file-sync-action](https://github.com/BetaHuhn/repo-file-sync-action) Action which runs on every push.
Expand Down
5 changes: 5 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ inputs:
description: |
Specify a different prefix for the new branch in the target repo. Defaults to repo-sync/SOURCE_REPO_NAME
required: false
FORK:
description: |
Specify the user account that will be used in a fork and pull-request workflow. Defaults
false.
required: false

outputs:
pull_request_urls:
Expand Down
45 changes: 39 additions & 6 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17261,6 +17261,9 @@ try {
BRANCH_PREFIX: getInput({
key: 'BRANCH_PREFIX',
default: 'repo-sync/SOURCE_REPO_NAME'
}),
FORK: getInput({
key: 'FORK'
})
}

Expand Down Expand Up @@ -17416,7 +17419,8 @@ const {
GITHUB_REPOSITORY,
OVERWRITE_EXISTING_PR,
PR_BODY,
BRANCH_PREFIX
BRANCH_PREFIX,
FORK
} = __nccwpck_require__(4570)

const { dedent, execCmd } = __nccwpck_require__(8505)
Expand Down Expand Up @@ -17458,6 +17462,28 @@ class Git {
await this.clone()
await this.setIdentity()
await this.getBaseBranch()

if (FORK) {
const forkUrl = `https://${ GITHUB_TOKEN }@github.com/${ FORK }/${ this.repo.name }.git`
await this.createFork()
await this.createRemote(forkUrl)

}
}

async createFork() {
core.debug(`Creating fork with OWNER: ${ this.repo.user } and REPO: ${ this.repo.name }`)
await this.github.repos.createFork({
owner: this.repo.user,
repo: this.repo.name
})
}

async createRemote(forkUrl) {
return execCmd(
`git remote add fork ${ forkUrl }`,
this.workingDir
)
}

async clone() {
Expand Down Expand Up @@ -17603,6 +17629,12 @@ class Git {
}

async push() {
if (FORK) {
return execCmd(
`git push -u fork ${ this.prBranch } --force`,
this.workingDir
)
}
return execCmd(
`git push ${ this.gitUrl } --force`,
this.workingDir
Expand All @@ -17614,7 +17646,7 @@ class Git {
owner: this.repo.user,
repo: this.repo.name,
state: 'open',
head: `${ this.repo.user }:${ this.prBranch }`
head: `${ FORK ? FORK : this.repo.user }:${ this.prBranch }`
})

this.existingPr = data[0]
Expand Down Expand Up @@ -17678,7 +17710,7 @@ class Git {
repo: this.repo.name,
title: title === undefined ? `${ COMMIT_PREFIX } Synced file(s) with ${ GITHUB_REPOSITORY }` : title,
body: body,
head: this.prBranch,
head: `${ FORK ? FORK : this.repo.user }:${ this.prBranch }`,
base: this.baseBranch
})

Expand Down Expand Up @@ -18020,7 +18052,8 @@ const {
OVERWRITE_EXISTING_PR,
SKIP_PR,
ORIGINAL_MESSAGE,
COMMIT_AS_PR_TITLE
COMMIT_AS_PR_TITLE,
FORK
} = __nccwpck_require__(4570)

const run = async () => {
Expand Down Expand Up @@ -18175,12 +18208,12 @@ const run = async () => {
core.notice(`Pull Request #${ pullRequest.number } created/updated: ${ pullRequest.html_url }`)
prUrls.push(pullRequest.html_url)

if (PR_LABELS !== undefined && PR_LABELS.length > 0) {
if (PR_LABELS !== undefined && PR_LABELS.length > 0 && FORK === undefined) {
core.info(`Adding label(s) "${ PR_LABELS.join(', ') }" to PR`)
await git.addPrLabels(PR_LABELS)
}

if (ASSIGNEES !== undefined && ASSIGNEES.length > 0) {
if (ASSIGNEES !== undefined && ASSIGNEES.length > 0 && FORK === undefined) {
core.info(`Adding assignee(s) "${ ASSIGNEES.join(', ') }" to PR`)
await git.addPrAssignees(ASSIGNEES)
}
Expand Down
5 changes: 5 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ try {
BRANCH_PREFIX: getInput({
key: 'BRANCH_PREFIX',
default: 'repo-sync/SOURCE_REPO_NAME'
}),
FORK: getInput({
key: 'FORK',
default: false,
disableable: true
})
}

Expand Down
35 changes: 32 additions & 3 deletions src/git.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ const {
GITHUB_REPOSITORY,
OVERWRITE_EXISTING_PR,
PR_BODY,
BRANCH_PREFIX
BRANCH_PREFIX,
FORK
} = require('./config')

const { dedent, execCmd } = require('./helpers')
Expand Down Expand Up @@ -58,6 +59,28 @@ class Git {
await this.clone()
await this.setIdentity()
await this.getBaseBranch()

if (FORK) {
const forkUrl = `https://${ GITHUB_TOKEN }@github.com/${ FORK }/${ this.repo.name }.git`
await this.createFork()
await this.createRemote(forkUrl)

}
}

async createFork() {
core.debug(`Creating fork with OWNER: ${ this.repo.user } and REPO: ${ this.repo.name }`)
await this.github.repos.createFork({
owner: this.repo.user,
repo: this.repo.name
})
}

async createRemote(forkUrl) {
return execCmd(
`git remote add fork ${ forkUrl }`,
this.workingDir
)
}

async clone() {
Expand Down Expand Up @@ -203,6 +226,12 @@ class Git {
}

async push() {
if (FORK) {
return execCmd(
`git push -u fork ${ this.prBranch } --force`,
this.workingDir
)
}
return execCmd(
`git push ${ this.gitUrl } --force`,
this.workingDir
Expand All @@ -214,7 +243,7 @@ class Git {
owner: this.repo.user,
repo: this.repo.name,
state: 'open',
head: `${ this.repo.user }:${ this.prBranch }`
head: `${ FORK ? FORK : this.repo.user }:${ this.prBranch }`
})

this.existingPr = data[0]
Expand Down Expand Up @@ -278,7 +307,7 @@ class Git {
repo: this.repo.name,
title: title === undefined ? `${ COMMIT_PREFIX } Synced file(s) with ${ GITHUB_REPOSITORY }` : title,
body: body,
head: this.prBranch,
head: `${ FORK ? FORK : this.repo.user }:${ this.prBranch }`,
base: this.baseBranch
})

Expand Down
7 changes: 4 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ const {
OVERWRITE_EXISTING_PR,
SKIP_PR,
ORIGINAL_MESSAGE,
COMMIT_AS_PR_TITLE
COMMIT_AS_PR_TITLE,
FORK
} = require('./config')

const run = async () => {
Expand Down Expand Up @@ -171,12 +172,12 @@ const run = async () => {
core.notice(`Pull Request #${ pullRequest.number } created/updated: ${ pullRequest.html_url }`)
prUrls.push(pullRequest.html_url)

if (PR_LABELS !== undefined && PR_LABELS.length > 0) {
if (PR_LABELS !== undefined && PR_LABELS.length > 0 && FORK === undefined) {
core.info(`Adding label(s) "${ PR_LABELS.join(', ') }" to PR`)
await git.addPrLabels(PR_LABELS)
}

if (ASSIGNEES !== undefined && ASSIGNEES.length > 0) {
if (ASSIGNEES !== undefined && ASSIGNEES.length > 0 && FORK === undefined) {
core.info(`Adding assignee(s) "${ ASSIGNEES.join(', ') }" to PR`)
await git.addPrAssignees(ASSIGNEES)
}
Expand Down

0 comments on commit 80e77fd

Please sign in to comment.