Skip to content

Instantly share code, notes, and snippets.

@alifeee
Last active February 2, 2025 17:57
Show Gist options
  • Save alifeee/d711370698f18851f1927f284fb8eaa8 to your computer and use it in GitHub Desktop.
Save alifeee/d711370698f18851f1927f284fb8eaa8 to your computer and use it in GitHub Desktop.
#!/bin/bash
# upload or update a file to a folder in a remote GitHub repository
# v1.0.0
# source:
# https://gist.github.com/alifeee/d711370698f18851f1927f284fb8eaa8
# for more info see
# https://blog.alifeee.co.uk/notes/uploading-files-to-a-git-hub-repository-with-a-bash-script/
# provide environment variables when executing script or with .env file
# example:
# export org="alifeee"
# export repo="blog"
# export fpath="notes/"
# export git_name="alifeee"
# export git_email="[email protected]"
# export GITHUB_TOKEN="github_pat_3890qwug8f989wu89gu98w43ujg98j8wjgj4wjg9j83wjq9gfj38w90jg903wj"
# ./upload_to_github.sh [file.txt]
# check file has been provided
file="${1}"
if [ -z "${file}" ]; then
echo "use: ./_upload.sh file.md"
exit 1
fi
filename=$(basename "${file}")
# print variables used
cat << EOF
using:
file: ${file}
filename: ${filename}
org: ${org}
repo: ${repo}
fpath: ${fpath}
git_name: ${git_name}
git_email: ${git_email}
GITHUB_TOKEN: ${GITHUB_TOKEN}
EOF
if [ -z "${org}" ] || [ -z "${repo}" ] || \
[ -z "${fpath}" ] || [ -z "${GITHUB_TOKEN}" ] || \
[ -z "${git_name}" ] || [ -z "${git_email}" ]; then
echo "one of the above variables is not set"
echo "please provide them with 'export' or using an .env file"
exit 1
fi
# url encode
urlencode() {
printf %s "$1" | jq -s -R -r @uri
}
# api URL
repos_api_url="https://api.github.com/repos/${org}/${repo}/contents/${fpath}"
# check if file exists
fue=$(urlencode "${filename}")
url="${repos_api_url}${fue}"
echo "testing if file exists"
echo "on URL: ${url}"
exists_req=$(curl -i -f -s -L \
-X GET \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"${url}")
status=$(echo "${exists_req}" | head -n1 | awk -F' ' '{print $2}')
if [[ "${status}" == 200 ]]; then
exists="1"
elif [[ "${status}" == 404 ]]; then
exists=""
else
echo "unexpected HTTP status: ${status}"
exit 1
fi
echo "got status: ${status}, exists set to '${exists}'"
# if it exists, we must include a sha1 of the existing file to prove we know what it was
# we also provide a base64 version of the file to upload
if [ -z "${exists}" ]; then
echo "new file, uploading..."
json_data='{"message":"uploaded '"${filename}"'","committer":{"name":"'"${git_name}"'","email":"'"${git_email}"'"},"content":"'"$(cat "${file}" | base64 -w0)"'"}'
else
echo "exists already, updating..."
response_content=$(echo "${exists_req}" | awk 'a==1{print} /^\r?$/{a=1}')
sha=$(echo "${response_content}" | jq -r '.sha')
json_data='{"message":"updated '"${filename}"'","committer":{"name":"'"${git_name}"'","email":"'"${git_email}"'"},"content":"'"$(cat "${file}" | base64 -w0)"'", "sha": "'"${sha}"'"}'
fi
echo "json data:"
echo "${json_data}"
result=$(cat "${file}" | base64 -w0 | curl -i -s -L \
-X PUT \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"${url}" \
-d "${json_data}")
status=$(echo "${result}" | head -n1 | awk -F' ' '{print $2}')
echo "got HTTP status ${status} from upload"
echo "I hope everything went ok!"
echo "check…"
echo "https://github.com/${org}/${repo}/commits/main/"
echo "https://github.com/${org}/${repo}/actions"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment