Forked Repo Write Access Success!

Finally found a somewhat decent way to handle the whole forked PR situation so that we can act on them… since GitHub Actions are pretty useful to many of us without that capability it is nice that this solution does solve most cases. It can also be somewhat simple for user to setup, but depending on the situation, not so easy on the developer side since you need to logically separate your app into stages.

Here is the general gist:

  1. Action runs like normal but detects if it is a read only environment
  2. When read only, I built a plugin for the Octokit library that serializes each request and tries to do a write action, if you rely on the return values from a given write request then you have to mock this and replace it when deserializing - which is the only more complex part of this flow.
  3. When running normally, everything completes as normal.
  4. When running read only, the plugin will package the serialized commands up and save them as an artifact with a specific key
  5. A schedule task is run on the workflow on a cron job which will quickly look for artifacts for that workflow , deserialize, and complete any outstanding flows
  6. Delete the artifacts when done so we dont waste space
  7. The whole thing is intelligent so that it will only create artifacts if it knows the schedule task is actually running as well so it won’t create artifacts if nothing will be there to process and delete them.

Essentially to make it work, the user just adds the schedule task to the workflow and it automates the rest for them:

name: "lint"
on: [pull_request]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: bradennapier/eslint-plus-action@v3

to

name: "lint"
on: 
  schedule:
    - cron: '*/15 * * * *'
  pull_request:
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: bradennapier/eslint-plus-action@v3

The schedule task always run against your master codebase so its important to understand that the workflow must exist on your master branch and need to be there for the workflow to run the updated code if you change it.

All secrets are available to the workflow and full write access

You will no longer be able to operate on the branch easily in the schedule task since the actions/checkout will have checked out your master branch. So in my case, I lint everything and serialize those results so that the schedule is not needing to do anything else. This may restrict some cases but generally there should be options.

Artifacts end up taking up long-term space of around 1Kb or less – and however much builds up before the sceduled task flushes them which should never last more than however long your cron is set for. As a bonus, those can be downloaded for debugging purposes nice and easy

I think most of this can be packaged up to be plug and play, although just getting it working was my main focus for the current build.

You can see the eslint runs successfully on forked PR here:

Hi @bradennapier,

Thanks for your sharing!

I created a workflow from the fork, use the sample code in the master branch, only pull_request event is triggered on the base repo, which i think is correct.
my PR: https://github.com/weide-zhou/ticket30/pull/4

I’m a little confused, how to check the write access?

Thanks.

The runner initially detects it doesn’t have write access so i built a plugin I attach to the GitHub toolkit which just captures each of the requests so they can be serialized.

This will only happen once you setup a scheduled task on the same workflow and that scheduled task runs.

Scheduled tasks only actually trigger on the master branch and they can take awhile the first run.

I am mobile at the moment so i can’t see what you did in the fork right now but hope that gets you going. I’ll try to check when I’m in office .

So basically everything runs normally if normal PR. If forked then it checks if it can detect that the scheduled task has ran in the last 24 hours. If it has it will serialize and build an artifact on the check which you can see and download. This artifact and any others for that workflow are downloaded when the schedule next runs and executed then those artifacts are deleted.

From a quick look, looks like your issue is that your master branch doesn’t have the schedule workflow so it won’t be running right now.