Search code examples
javascripthtmlexpressgithubrequest

Programmatically adding a file in a Github repository in JavaScript and HTML


I've been trying to update a file to my GitHub repository through my code to create an automated system that pushes changes automatically. I tried creating a function that 'adds' a file using a GitHub access token, and tried to get the repo and push to it. Then in my HTML file, I have a button that runs this function through an onclick event. Here is what I tried:

function upload() {
  return fetch(
    `https://api.github.com/repos/MY-USERNAME/MY-REPO-NAME/contents/amogus.html`,
    {
      method: "PUT",
      headers: {
        Accept: "application/vnd.github+json",
        Authorization: `Bearer {MY ACCESS TOKEN HERE}`
      },
      body: JSON.stringify({
        message: "amogus",
        content: "aaaaa"
      })
    }
  ).then((res) => res.json());
}

EDIT

I figured it out. Apparently, GitHub only supports Bse64 encoded files, so you only have to convert your file data TO Base64 using the following code:

content: btoa("your text here")

This converts your file content to Base64, which can be uploaded to GitHub.

This unfortunately does not do anything to the repo and does not return any errors. Am I doing anything wrong? Thank you.


Solution

  • You need to include the "sha" parameter when updating a file. Please refer to GitHub's REST API for create or update file contents for detailed information.

    The "sha" parameter represents the blob SHA of the file that is being replaced. To find the blob SHA, you can perform a GET request for the file you wish to update.

    The provided code first sends a GET request to retrieve the SHA of the existing file. If the file already exists, the response will contain the "sha" property. In this case, existingFile.sha will hold the SHA of the file to be replaced. If the file is new and doesn't exist yet, the response will not include the "sha" property, and existingFile.sha will be undefined. Finally, the code proceeds with the PUT request you were attempting to perform.

    async function upload() {
      const message = 'amogus';
      const content = 'aaaaa';
      const owner = 'MY-USERNAME';
      const repo = 'MY-REPO-NAME';
      const path = 'amogus.html';
      const auth = '{MY ACCESS TOKEN HERE}';
    
      const existingFile = await (await fetch(
        `https://api.github.com/repos/${owner}/${repo}/contents/${path}`,
        {
          method: 'GET',
          headers: {
            Accept: 'application/vnd.github+json',
            Authorization: `Bearer ${auth}`
          }
        }
      )).json();
    
      await (await fetch(
        `https://api.github.com/repos/${owner}/${repo}/contents/${path}`,
        {
          method: 'PUT',
          headers: {
            Accept: 'application/vnd.github+json',
            Authorization: `Bearer ${auth}`
          },
          body: JSON.stringify({
            message: message,
            content: btoa(content),
            sha: existingFile.sha,
          }),
        }
      )).json();
    }