Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Previewing PR using Surge.sh #1487

Merged
merged 17 commits into from
Mar 8, 2021

Conversation

raysonkoh
Copy link
Contributor

@raysonkoh raysonkoh commented Feb 24, 2021

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • Others, please explain:

Related to #1466

Currently, we have provided instructions for deploying PR previews using Netlify. However, as Netlify have a limited amount of free build minutes, there may be other users who are thinking of using other PR preview services. This PR aims to add instructions for previewing PR using Surge which has unlimited build minutes as of now.

Overview of changes:

Add 2 new workflows for previewing PR on Surge.

The first workflow is "Receive Markbind PR" which builds the markbind site and uploads it as an Artifact.

The next workflow is "Deploy PR Preview", which is only triggered upon successful completion of the first workflow and it deploys the Markbind site to Surge.sh using with the link as such: https://pr-[PR_NUMBER]-[REPO_SLUG].surge.sh. At the end of this workflow, a github-actions bot will auto-comment the link of the PR preview for easier accessibility for the PR reviewer.

Anything you'd like to highlight / discuss:
Some relevant context: reposense/RepoSense#1105, reposense/RepoSense#1099 , reposense/RepoSense#1411, reposense/RepoSense#1434

The main reason for having 2 separate workflows is due to security reasons. Github-Actions does not expose repo secrets for workflows that are triggered by PRs from a forked repo, link to docs. Based on my research so far, there are four possible ways to get around this.

  1. Using the pull_request_target event, the workflow that are triggered by PRs are able to get access to repo secrets. More info in the github release doc. However, by design, it does not run the code in the PR as it may be malicious. One workaround that people have found would be to use pull_request_target and then checking out the HEAD of the PR. However, this poses a serious security risk as the secrets would be leaked.
  2. Using the workflow_run event, together with a separate initial workflow which is then used to trigger the main workflow. This is the approach that Reposense is currently using and the approach that I adopted for this PR. I feel that this is much more secure than the first option as we can control which section of the PR code to extract to the main workflow (that is deploys the Markbind site to Surge).
  3. Ensure every user sending a PR from their forked repo has their own SURGE_TOKEN
  4. Merging the PR into a separate branch in the main repo, and sending a PR from that branch to master.

Option 2 is also recommended by Github here: https://securitylab.github.com/research/github-actions-preventing-pwn-requests. Option 3 and 4 may be too tedious and inconvenient.

Testing instructions:

  1. Create a Surge account by first installing Surge using npm install --global surge and typing surge on the terminal
  2. Next, get type surge token to generate your surge token.
  3. In your markbind site repo, create a new secret by going to "Settings"->"Secrets" and name the key as SURGE_TOKEN and set the value as the generated surge token.
  4. Commit and push the following 2 files into your markbind site repo, in the directory ./github/workflows/.
receivePR.yml
name: Receive Markbind PR

# read-only
# no access to secrets
on:
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:        
      - uses: actions/checkout@v2
      - name: Install Node
        uses: actions/setup-node@v2
        with:
          node-version: 10
      - name: Build Markbind website
        if: ${{ success() && github.event_name == 'pull_request' }}
        run: |
          npm install -g markbind-cli
          markbind build
      - name: Save PR number and HEAD commit
        if: ${{ success() && github.event_name == 'pull_request' }}
        run: |
          mkdir -p ./pr
          echo ${{ github.event.number }} > ./pr/NUMBER
          echo ${{ github.event.pull_request.head.sha }} > ./pr/SHA
      - name: Upload artifacts 
        if: ${{ success() && github.event_name == 'pull_request' }}
        uses: actions/upload-artifact@v2
        with:
          name: markbind-deployment
          path: |
            ./_site
            ./pr


previewPR.yml
name: Deploy PR Preview

# Runs after PR is received and build by markbind-cli
# Has access to repo secrets
on:
  workflow_run:
    workflows: ["Receive Markbind PR"]
    types:
      - completed

jobs:
  build:
    runs-on: ubuntu-latest
    name: Deploying to surge
    steps:
      - uses: actions/checkout@v2
      - name: Download artifact
        uses: dawidd6/action-download-artifact@v2
        with:
          workflow: receivePR.yml
          run_id: ${{ github.event.workflow_run.id }}
          name: markbind-deployment
          path: .
      - name: Display structure of downloaded files
        run: ls -R
      - name: Extract PR number
        id: pr-number
        run: echo '::set-output name=ACTIONS_PR_NUMBER::'$(cat ./pr/NUMBER)
      - name: Install Node
        uses: actions/setup-node@v2
        with:
          node-version: 10
      - name: Inject slug/short variables
        uses: rlespinasse/github-slug-action@v3.x
      - name: Build PR preview url
        id: pr-url
        run: echo '::set-output name=ACTIONS_PREVIEW_URL::'https://pr-${{ steps.pr-number.outputs.ACTIONS_PR_NUMBER }}-${{ env.GITHUB_REPOSITORY_SLUG_URL }}.surge.sh/
      - name: Install surge and deploy PR to surge
        run: |
          npm i -g surge
          surge --project ./_site --domain ${{ steps.pr-url.outputs.ACTIONS_PREVIEW_URL }}
        env:
          SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }}
      - name: Find PR preview link comment
        uses: peter-evans/find-comment@v1
        id: fc
        with:
          issue-number: ${{ steps.pr-number.outputs.ACTIONS_PR_NUMBER }}
          body-includes: Your PR can be previewed
      - name: Comment PR preview link in PR
        if: ${{ steps.fc.outputs.comment-id == 0 }}
        uses: peter-evans/create-or-update-comment@v1
        with:
          issue-number: ${{ steps.pr-number.outputs.ACTIONS_PR_NUMBER }}
          body: |
            Thank you for submitting the Pull Request! :thumbsup: 

            Your PR can be previewed [here](${{ steps.pr-url.outputs.ACTIONS_PREVIEW_URL }})

  1. Test the workflow by creating PRs from a branch and from a forked repo, if everything goes well, the github-actions bot should auto-comment the link of the PR preview and the link should render the updated Markbind site.

Showcase:

Proposed commit message: (wrap lines at 72 characters)

Add support for PR previews using Surge

Netlify's deploy preview feature may not be suitable for certain
Markbind users due to its limited build minutes.

Expanding support for PR previews via Surge would cater to such
users due to its unlimited build minutes.

Let's add instructions in the userGuide for setting up PR
previews with Surge.

Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No blatantly unrelated changes
  • Pinged someone for a review!

@ang-zeyu
Copy link
Contributor

Thanks a lot for the work here! @raysonkoh

Could I double check the resolution in the issue was per @damithc's comment here?

i.e. we're not actually going to switch to surge for this repo, just provide instructions / pointers (documentation) for ways of doing pr previews, which sounds good.

if this pr is meant as a poc toward those documentation changes / some other purpose however please ignore this 😅

@raysonkoh
Copy link
Contributor Author

raysonkoh commented Feb 24, 2021

if this pr is meant as a poc toward those documentation changes / some other purpose however please ignore this 😅

Thanks for the comment @ang-zeyu Yes, I was thinking along this line.

Would this be the right approach or do you think updating the userGuide with the instructions is enough?

@ang-zeyu
Copy link
Contributor

Thanks for the comment @ang-zeyu Yes, I was thinking along this line.

Would this be the right approach or do you think updating the userGuide with the instructions is enough?

The example here looks really robust, and can serve as a good accompanying example somewhere.

I was thinking of adding a separate supporting top level section / page first (something like Deployment for PR previews?) under https://markbind-master.netlify.app/userguide/deployingthesite?

Something along this structure:

  • general pointers / things to take note for pr previews with MarkBind, if any

On those lines since we only have instructions for deploying to github pages, netlify, a prior pr for a deploying to surge guide (in non-pr preview context) based on the first workflow here could be done as well to reduce the content repitition.

What do you think? @raysonkoh

@raysonkoh
Copy link
Contributor Author

Thanks for the suggestion! Just to clarify, you are suggesting to have another PR for adding instructions for deploying a Markbind site to Surge? Actually the steps are roughly the same, with an additional step of adding a CNAME file to the root of the repo. Is that what you mean by reducing content repetition?

Based on what you said, I think a good page structure for deployingTheSite would be:

  1. Deploying to Github Pages
    1. Using the markbind deploy command
    2. Using CI tools
      1. Github Actions
      2. Travis CI
      3. Appveyor CI
      4. Circle CI
  2. Deploying to Netlify
  3. Previewing PRs for Markbind sites
    1. Using Netlify's Deploy Previews feature
    2. Using Surge.sh

What do you think @ang-zeyu ?

@ang-zeyu
Copy link
Contributor

Actually the steps are roughly the same, with an additional step of adding a CNAME file to the root of the repo. Is that what you mean by reducing content repetition?

I suppose so. I'm not too familiar with Surge however, I'll leave you to judge whether its worth it here 😅

  • Deploying to Netlify

  • Deploying to Surge (added)

  • Previewing PRs for Markbind sites

    1. Using Netlify's Deploy Previews feature
    2. Using Surge.sh

With the above addition*, if it makes sense

@raysonkoh
Copy link
Contributor Author

Actually the steps are roughly the same, with an additional step of adding a CNAME file to the root of the repo. Is that what you mean by reducing content repetition?

I suppose so. I'm not too familiar with Surge however, I'll leave you to judge whether its worth it here 😅

  • Deploying to Netlify

  • Deploying to Surge (added)

  • Previewing PRs for Markbind sites

    1. Using Netlify's Deploy Previews feature
    2. Using Surge.sh

With the above addition*, if it makes sense

Actually, I feel that we can put this (including a section for Deploying a Markbind site to Surge for production) aside for now, because there isn't really anything that Surge provides that Github Pages doesn't provide and setting up Surge is more troublesome than setting up Github Pages. Cost-wise, both services are free also.

@raysonkoh
Copy link
Contributor Author

I will make a separate PR to reorganize the page structure of deployingTheSite first, so that the changes for this PR will solely be adding instructions for previewing PR using Surge.

@raysonkoh raysonkoh mentioned this pull request Feb 25, 2021
10 tasks
@raysonkoh raysonkoh marked this pull request as ready for review March 1, 2021 05:52
@raysonkoh raysonkoh changed the title [WIP] Support Previewing PR using Surge.sh Support Previewing PR using Surge.sh Mar 1, 2021
Copy link
Contributor

@jonahtanjz jonahtanjz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work on this :) The instructions are clear and straightforward. Managed to set up my surge preview very quickly following the steps 👍. Just two minor nits and the rest looks good.

docs/userGuide/deployingTheSite.md Outdated Show resolved Hide resolved

<include src="screenshot.md" boilerplate var-alt="Create Surge account" var-file="surgeCreateAccount.png" inline />

1. Proceed to create a Surge account.
Copy link
Contributor

@jonahtanjz jonahtanjz Mar 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps can also include instruction to inform the user to press 'Enter' to proceed to use the default values of project and domain when setting up the account? New users may be confused by this step.

image

Copy link
Contributor Author

@raysonkoh raysonkoh Mar 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this part is not needed - the user can just CTRL-C out of this process (after logging in / creating an account). I have added a clarification in the userGuide on this. Could you help to check to see if it is clearer?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this part is not needed - the user can just CTRL-C out of this process (after logging in / creating an account).

Ahh I see. Yup it's much clearer now 👍 Thanks for updating :)

- Fix gh-action workflow directory path
- Make the steps in setting up Surge clearer
Copy link
Contributor

@ang-zeyu ang-zeyu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work with the docs! @raysonkoh

The main reason for having 2 separate workflows is due to security reasons. Github-Actions does not expose repo secrets for workflows that are triggered by PRs from a forked repo, link to docs. Based on my research so far, there are four possible ways to get around this.

Agree with the approach here, thanks for the research.


Just a few suggestions on the workflow examples:

docs/userGuide/deployingTheSite.md Outdated Show resolved Hide resolved
docs/userGuide/deployingTheSite.md Outdated Show resolved Hide resolved
run_id: ${{ github.event.workflow_run.id }}
name: markbind-deployment
path: .
- name: Display structure of downloaded files
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we remove this step? since devs can include it as needed if preferred

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup make sense, will remove it

docs/userGuide/deployingTheSite.md Outdated Show resolved Hide resolved
uses: rlespinasse/github-slug-action@v3.x
- name: Build PR preview url
id: pr-url
run: echo '::set-output name=ACTIONS_PREVIEW_URL::'https://pr-${{ steps.pr-number.outputs.ACTIONS_PR_NUMBER }}-${{ env.GITHUB_REPOSITORY_SLUG_URL }}.surge.sh/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we remove rlespinasse/github-slug-action@v3.x and simplify the surge url?

also a small comment / note to change this as appropriate, since the url is project-dependent

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I think that if we remove rlespinasse/github-slug-action@v3.x, it will add some more complexity since there needs to be some regex script to extract the repoSlug. I am not sure if there is a way to simplify the surge url while ensuring that it is still as general as possible.

I can add a note to say that the user can make modifications to the surge URL as needed to a simpler one, together with a short code snippet showing the relevant changes. What do you think @ang-zeyu ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not too familiar with surge's specifics - is ${{ env.GITHUB_REPOSITORY_SLUG_URL }} necessary / convention for pr previewing in surge?

my view is that this could be easily configured to something unique if the user wants to (not limited to owner + repo format).
i.e. just https://pr-${{ steps.pr-number.outputs.ACTIONS_PR_NUMBER }}-xxxx-anything-xxxx.surge.sh.
Would that work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One way is that the user can have a SURGE_URL secret, so the PR URL would be something like https://pr-${{ steps.pr-number.outputs.ACTIONS_PR_NUMBER }}-${{ secrets.SURGE_URL }}.surge.sh.

This would eliminate the need for rlespinasse/github-slug-action@v3.x in the code. However, this would be slightly more inconvenient for the user.

What do you think about this approach?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm was thinking of just highlighting that the specific line in the .yml should be edited per the project as needed before committing. (comment / warning box / highlight)
Since folks who are using pull requests, github actions, github likely have the know how =P

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I have added in the userGuide a new variable PR_URL which the user can modify. I have also added a note to highlight to the user that they have to edit the PR_URL according to their needs.

Additionally, **when contributors make a pull request to your GitHub repo, you can _preview_ the updated site** at the bottom of the pull request by clicking on `details` link in the PR:
## Previewing Pull Requests for MarkBind sites

There may be more than one user making changes to your MarkBind site. In such cases, it might be prudent to have a workflow that is centered around pull requests (PRs) such as a [feature branch workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow) or a [forking workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/forking-workflow).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's preface a little bit more who this section is for (users having MarkBind projects on github)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I have added an info box below ## Previewing Pull Requests for MarkBind sites

Copy link
Contributor

@ang-zeyu ang-zeyu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks! one last nit:


<box type="info">

This section is meant for users who are $$hosting their Markbind project on **Github**$$.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's keep this to 2nd person for consistency

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I have updated this to 2nd person

Copy link
Contributor

@ang-zeyu ang-zeyu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm 👍

@ang-zeyu ang-zeyu added this to the v3.0 milestone Mar 8, 2021
@ang-zeyu ang-zeyu merged commit 1ecbf9a into MarkBind:master Mar 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants