Last active
February 2, 2025 17:57
-
-
Save alifeee/d711370698f18851f1927f284fb8eaa8 to your computer and use it in GitHub Desktop.
upload a file to a github repository with the API. see https://blog.alifeee.co.uk/notes/uploading-files-to-a-git-hub-repository-with-a-bash-script/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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