[TUTORIAL] How to auto-update your project with GitHub


#1

Project URL: glitch/edit/ded-tihon

Hi! Recently I asked on the forum whether it is possible to automatically update my project with a pull-request on GitHub? I was answered by cori, by giving me a great idea how you can implement integration with GitHub yourself.

Here is the plan:
Git repo (using webhooks) makes a POST-request to the address {project}.glitch.me/git, and the project executes the .sh script, and then reloads the project with the command refresh.

NOTE: you will need to create remote branch using git remote add origin {url}

To get started, create a project or go to an already created one. You will need the pre-installed express package. We will need to create a path for request - for example, /git.

app.post('/git', (req, res) => {
  // If event is "push"
  if (req.headers['x-github-event'] == "push") { 
    /* Here will be our updating code */
  }

  return res.sendStatus(200); // Send back OK status
});

NOTE: req.headers['x-github-event'] checks if it is a GitHub event and checks if it is "push"

Next, we want to install node-cmd package to run bash commands. Include it somewhere above.

const cmd = require("node-cmd");

Then, let’s update or code for updating block!

if (req.headers['x-github-event'] == "push") {
  cmd.run('chmod 777 git.sh'); /* :/ Fix no perms after updating */
  cmd.get('./git.sh', (err, data) => {  // Run our script
    if (data) console.log(data);
    if (err) console.log(err);
  });
  cmd.run('refresh');  // Refresh project

  console.log("> [GIT] Updated with origin/master");
}

Fill git.sh with this code:

#/bin/sh

# Fetch the newest code
git fetch origin master

# Hard reset
git reset --hard origin/master

# Force pull
git pull origin master --force

That’s all! Next: create new webhook in your repo’s settings.

Time to test it out! Good luck!

UPD: If you don’t want to let stranger make POST request to refresh your project and, maybe, break something, add some secrets!

image

image

New field appeared!

Then, update code as following:

const crypto = require("crypto"); // pre-installed node package
...
  let hmac = crypto.createHmac("sha1", process.env.SECRET);
  let sig  = "sha1=" + hmac.update(JSON.stringify(req.body)).digest("hex");
  
  if (req.headers['x-github-event'] == "push" && 
      sig == req.headers['x-hub-signature']) {
    ...
  }
}

BONUS
image

let commits = req.body.head_commit.message.split("\n").length == 1 ?
              req.body.head_commit.message :
              req.body.head_commit.message.split("\n").map((el, i) => i !== 0 ? "                       " + el : el).join("\n");
console.log(`> [GIT] Updated with origin/master\n` + 
            `        Latest commit: ${commits}`);

#2

Hey @jarvis394,

Thanks for the explanation! :tada:
How could you possibly do the reciprocal with Glitch?
For instance, fetch the GitHub repository and update the code of the project, however, without doing it manually.
If you could possibly create a guide for…
Thanks, anyway.


#3

Very nice work, @jarvis394, thanks for putting it together!

It might also be worth adding the process for setting up the information to handle the X-Hub-Signature that goes along with the secret on the webhook - this is a way to enable folks implementing this to verify that the request is genuinely coming from GitHub, and isn’t just some random internet person hitting your `/git endpoint.


#4

If I understand you correctly, this tutorial has been already made for Glitch. Visit my project (from line 92) to see, how it works.
(i’m just simply using Glitch for hosting, not code-editing, so i’ve made that to automate my work).


#5

Hello, cori,
Updated, thanks!


#6

Nice work, though I’ve seen this somewhere idk
You can look into not using node-cmd and using node’s child process to reduce dependencies