How to upload local file to GitHub using cURL? - github

I try to use cURL to upload a local file (e.g. docx, jpeg...) to GitHub repository? How can I specify the local file location and upload it to GitHub?
curl -X "PUT" \
-H "Accept: application/vnd.github+json" \
-H "Authorization: token <token>" \
https://api.github.com/repos/BT23/demo-repo/contents/hello.txt \
-d '{
"message":"Upload this file to Git",
"committer":{"name":"Bon", "email":"bon#bon.com"},
"content":{"$(openssl base64 -A in $/temp/hello.txt)"}
}'
Thanks

As an alternative, you can separate the content encoding from the curl call.
See this gist
content=$(cat /temp/hello.txt | base64)
curl -X "PUT" \
-H "Accept: application/vnd.github+json" \
-H "Authorization: token <token>" \
https://api.github.com/repos/BT23/demo-repo/contents/hello.txt \
-d '{
"message":"Upload this file to Git",
"committer":{"name":"Bon", "email":"bon#bon.com"},
"content":"${content}"}
}'

Related

Github REST Api get workflow runs for a specific date range with cURL

I am trying to query Github's REST API to list workflow runs for specific date ranges.
Here's an example curl call:
curl \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_ACCESS_TOKEN" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/[OWNER]/[REPO]/actions/runs?created:2023-01-01..2023-01-02"
From what I understand from the documentation, this is how I should be able to retrieve only results from Jan 1st and 2nd of 2023. But it does not work, my result is always the latest runs.
What am I doing wrong?
you should use the = symbol instead of :, like:
curl \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_ACCESS_TOKEN" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/[OWNER]/[REPO]/actions/runs?created=2023-01-01..2023-01-02"

How do I download a file from a GitHub draft

I am using AppVeyor to set up the CI for a GitHub repository and upload the build artifacts to a draft named CI builds. The file is e.g. located under
https://github.com/an_organisation/a_project/releases/tag/untagged-1111aaaacccc0000dddd/filename.tar.gz
and can be accessed and downloaded from a browser.
Now I would like to access those uploaded artifact from another AppVeyor project (i.e. an appveyor.yml script). I tried without success to download with AppVeyor DownloadFile command, curl, and wget using the following commands
set DOWNLOAD_FILENAME=filename.tar.gz
set DOWNLOAD_ADDRESS=https://github.com/an_organisation/a_project/releases/download/untagged-1111aaaacccc0000dddd/$DOWNLOAD_FILENAME
wget --header "Authorization: token $GH_AUTH_TOKEN" --output-document=$DOWNLOAD_FILENAME $DOWNLOAD_ADDRESS
wget --auth-no-challenge --header "Accept:application/octet-stream" --output-document=$DOWNLOAD_FILENAME "$DOWNLOAD_ADDRESS?access_token:$GH_AUTH_TOKEN"
curl -fsSL -G --user "$APPVEYOR_ACCOUNT_NAME:$GH_AUTH_TOKEN" -o $DOWNLOAD_FILENAME $DOWNLOAD_ADDRESS
curl -fsSL -G -H "Authorization: token $GH_AUTH_TOKEN" -H "Accept: application/octet-stream" -o $DOWNLOAD_FILENAME $DOWNLOAD_ADDRESS
curl -fsSL -G -H "Authorization: token $GH_AUTH_TOKEN" -H "Accept: application/octet-stream" -o $DOWNLOAD_FILENAME https://api.github.com/repos/an_organisation/a_project/releases/download/untagged-1111aaaacccc0000dddd/
Slowly I get a feeling that a file download from a draft via GitHub API or download link is not possible.
What is the correct command to download such a file?
TLDR Use the Get Release asset API with header Accept: application/octet-stream :
curl -OJ -L -H "Accept: application/octet-stream" \
-H "Authorization: Token $YOUR_TOKEN" \
"https://api.github.com/repos/$REPO/releases/assets/$ASSET_ID"
You need to have the assetID. In order to have it you need the releaseID if you have not already this information use GET /repos/:user/:repo/releases :
curl -s -H "Authorization: Token $YOUR_TOKEN" \
"https://api.github.com/repos/$REPO/releases" | jq '.[] | {(.name): .id}'
Then get the assets IDs use GET /repos/:user/:repo/releases/:release_id :
curl -s -H "Authorization: Token $YOUR_TOKEN" \
"https://api.github.com/repos/$REPO/releases/$RELEASE_ID" | \
jq -r '.assets[] | {(.id |tostring): .name}'
Then once you have assetID (maybe you already had it btw) you can finally use GET /repos/:user/:repo/releases/assets/:asset_id with header Accept: application/octet-stream. From the documentation :
To download the asset's binary content, set the Accept header of the
request to application/octet-stream. The API will either redirect the
client to the location, or stream it directly if possible. API clients
should handle both a 200 or 302 response.
The following download the file locally :
curl -OJ -L -H "Accept: application/octet-stream" \
-H "Authorization: Token $YOUR_TOKEN" \
"https://api.github.com/repos/$REPO/releases/assets/$ASSET_ID"

Cloudflare DDNS repeat sh script using API v4, with multiple A record in a single sh script, but fail

I am trying to use Cloudflare API v4 to setup DDNS on my server. But I am new in scripting .sh file. I hope to update multiple DNS records in a single .sh file.
I got a script from the internet (script1.sh):
NEW_IP=`curl -s http://ipv4.icanhazip.com`
CURRENT_IP=`cat /Users/foo/Desktop/cloudflare/current_ip.txt`
if [ "$NEW_IP" = "$CURRENT_IP" ]
then
echo "No Change in IP Adddress"
else
curl -X PUT "https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/{dns_record_id}" \
-H "X-Auth-Email: {my_email}" \
-H "X-Auth-Key: {global_api_key}" \
-H "Content-Type: application/json" \
--data '{"type":"A","name":"{domain_name}","content":"'$NEW_IP'","ttl":1,"proxied":true}'
echo $NEW_IP > /Users/foo/Desktop/cloudflare/current_ip.txt
fi
The above script is work fine for single DNS record update instead of multiple record update like below (script2.sh):
NEW_IP=`curl -s http://ipv4.icanhazip.com`
CURRENT_IP=`cat /Users/foo/Desktop/cloudflare/current_ip.txt`
if [ "$NEW_IP" = "$CURRENT_IP" ]
then
echo "No Change in IP Adddress"
else
#domain-one
curl -X PUT "https://api.cloudflare.com/client/v4/zones/{zone_id_for_domain_one}/dns_records/{dns_record_id_for_domain_one_record_one}" \
-H "X-Auth-Email: {my_email}" \
-H "X-Auth-Key: {global_api_key}" \
-H "Content-Type: application/json" \
--data '{"type":"A","name":"domain-one.com","content":"'$NEW_IP'","ttl":1,"proxied":true}'
curl -X PUT "https://api.cloudflare.com/client/v4/zones/{zone_id_for_domain_one}/dns_records/{dns_record_id_for_domain_one_record_two}" \
-H "X-Auth-Email: {my_email}" \
-H "X-Auth-Key: {global_api_key}" \
-H "Content-Type: application/json" \
--data '{"type":"A","name":"subdomain.domain-one.com","content":"'$NEW_IP'","ttl":1,"proxied":true}'
#domain-two
curl -X PUT "https://api.cloudflare.com/client/v4/zones/{zone_id_for_domain_two}/dns_records/{dns_record_id_for_domain_two_record}" \
-H "X-Auth-Email: {my_email}" \
-H "X-Auth-Key: {global_api_key}" \
-H "Content-Type: application/json" \
--data '{"type":"A","name":"domain-two.com","content":"'$NEW_IP'","ttl":1,"proxied":true}'
echo $NEW_IP > /Users/foo/Desktop/cloudflare/current_ip.txt
fi
Can you please help to explain and solve the problem? Please tell me what's wrong in the script. Thanks!
[edit] I run it once by sh /Users/foo/Desktop/script-name.sh, for the first example (script1.sh), it is ok; for second example (script2.sh), return -bash: fork: Resource temporarily unavailable. As I use automatic run script like cron, it is same result.
Every curl request done, needed to add & or && to continue the following function.
More explanation here.
NEW_IP=`curl -s http://ipv4.icanhazip.com`
CURRENT_IP=`cat /Users/foo/Desktop/cloudflare/current_ip.txt`
if [ "$NEW_IP" = "$CURRENT_IP" ]
then
echo "No Change in IP Adddress"
else
#domain-one
curl -X PUT "https://api.cloudflare.com/client/v4/zones/{zone_id_for_domain_one}/dns_records/{dns_record_id_for_domain_one_record_one}" \
-H "X-Auth-Email: {my_email}" \
-H "X-Auth-Key: {global_api_key}" \
-H "Content-Type: application/json" \
--data '{"type":"A","name":"domain-one.com","content":"'$NEW_IP'","ttl":1,"proxied":true}' &
curl -X PUT "https://api.cloudflare.com/client/v4/zones/{zone_id_for_domain_one}/dns_records/{dns_record_id_for_domain_one_record_two}" \
-H "X-Auth-Email: {my_email}" \
-H "X-Auth-Key: {global_api_key}" \
-H "Content-Type: application/json" \
--data '{"type":"A","name":"subdomain.domain-one.com","content":"'$NEW_IP'","ttl":1,"proxied":true}' &
#domain-two
curl -X PUT "https://api.cloudflare.com/client/v4/zones/{zone_id_for_domain_two}/dns_records/{dns_record_id_for_domain_two_record}" \
-H "X-Auth-Email: {my_email}" \
-H "X-Auth-Key: {global_api_key}" \
-H "Content-Type: application/json" \
--data '{"type":"A","name":"domain-two.com","content":"'$NEW_IP'","ttl":1,"proxied":true}'
echo $NEW_IP > /Users/foo/Desktop/cloudflare/current_ip.txt
fi
After going through many posts on this topic I've ended up taking parts from a number posts and settled for the below.
The below will loop through the entries in the array "dnsrecords" and update each with the machines current external address.
Have had a little more time to look into this, I wanted it to run it on my NGINX server as a cronjob and update multiple records, some to be proxied and others not.
Still want to make some of the below into functions, but for now it is working as I need it to.
And it also logs onto a "log.log" file on every run.
#!/usr/bin/bash
## Cloudflare authentication details
## Keep these private
cloudflare_auth_email=Your_Email
cloudflare_auth_key="Your_API_Key"
zoneid="Your_Zone_ID"
## Cloudflare Proxied DNS Records as Array
dnsrecords_proxied=(
"domain.com"
"www.domain.com"
"sub1.domain.com"
"sub2.domain.com"
"sub3.domain.com"
"sub3.domain.com"
)
## Cloudflare Non-Proxied DNS Records as Array
dnsrecords_not_proxied=(
"vpn01.domain.com"
"vpn02.domain.com"
)
## Files to log to (replace "path/to/" with script path)
log=path/to/log.log
log_ip=path/to/previous_ip
## Getting Date/Time
dt=$(date '+%d/%m/%Y %H:%M:%S')
## Get old IP from file
old_ip=$(cat $log_ip)
## Get the current external IP address
ip=$(curl -s -X GET https://api.ipify.org)
#echo "Current IP is $ip"
## Checking if IP changed since last update
if [ $ip = $old_ip ]; then
echo -en "$dt - Previous IP:$old_ip\n$dt - Current IP:$ip\n$dt - No Changes Required....\n" >> $log
echo "$(tail -n 1000 $log)" > $log
exit
## Exit if IP has not changed
else
## If the IP changed, not match the one on file "previous_ip"
echo -en "$dt - Previous IP:$old_ip\n$dt - Current IP:$ip\n$dt - Starting Updates....\n" >> $log
## Processing Proxied DNS Records
for dnsrecord in "${dnsrecords_proxied[#]}"
do
## For each DNS Record in Array "dnsrecords"
# Getting the DNS Record ID
dnsrecordid=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records?type=A&name=$dnsrecord" \
-H "X-Auth-Email: $cloudflare_auth_email" \
-H "Authorization: Bearer $cloudflare_auth_key" \
-H "Content-Type: application/json" | jq -r '{"result"}[] | .[0] | .id') &&
# Updating the DNS Record
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records/$dnsrecordid" \
-H "X-Auth-Email: $cloudflare_auth_email" \
-H "Authorization: Bearer $cloudflare_auth_key" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"$dnsrecord\",\"content\":\"$ip\",\"ttl\":1,\"proxied\":true}" | jq
echo -en "$dt - Updated - $dnsrecord \n" >> $log
done
## Processing Non Proxied DNS Records
for dnsrecord in "${dnsrecords_not_proxied[#]}"
do
## For each DNS Record in Array "dnsrecords"
# Getting the DNS Record ID
dnsrecordid=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records?type=A&name=$dnsrecord" \
-H "X-Auth-Email: $cloudflare_auth_email" \
-H "Authorization: Bearer $cloudflare_auth_key" \
-H "Content-Type: application/json" | jq -r '{"result"}[] | .[0] | .id') &&
# Updating the DNS Record
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records/$dnsrecordid" \
-H "X-Auth-Email: $cloudflare_auth_email" \
-H "Authorization: Bearer $cloudflare_auth_key" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"$dnsrecord\",\"content\":\"$ip\",\"ttl\":1,\"proxied\":false}" | jq
echo -en "$dt - Updated - $dnsrecord \n" >> $log
done
echo $ip > $log_ip
echo -en "$dt - Updates Completed.... \n" >> $log
echo "$(tail -n 1000 $log)" > $log
fi

POST request to google cloud storage using Curl

In the following Curl command, content type and content length and access bearer are attached to my bucket URI to upload a file to google cloud storage.
C:\softwares\curl>curl -X POST -H "Content-Type:application/json" \
-H "Content-Length:100" \
-H "Authorization: Bearer <MY_OAUTH2_TOKEN>" \
"https://www.googleapis.com/upload/storage/v1/b/kids-74096.appspot.com/o?uploadType=media&name=newcurl" \
-d '{"text":"something"}'
But I am getting this error:
curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)
Make sure to include a Content-Type header, and ensure that your Content-Length matches the length of the data you're sending. Here's an example:
curl -k -v -X POST \
-H "Authorization: Bearer <your_oauth2_token>" -H "Content-Length: 8" \
-H "Content-Type: text/plain" \
'https://www.googleapis.com/upload/storage/v1/b/your-bucket/o?uploadType=media&name=yourobjectname' \
-d 'yourdata'
As suggested in the comments, you might find it easier to use gsutil or the Cloud Storage client libraries to accomplish this.

Box -> View API -> Can not authenticate to create session

in this site :https://developers.box.com/view/
I do follow the instruction in the example (use Postman or curl)
curl https://view-api.box.com/1/sessions \
-H "Authorization: Token YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"document_id": "ABC123"}' \
-X POST
YOUR_API_KEY is replaced by my api key
ABC123 is replaced by a my pdf file.
But I got result: {"message": "Unsupported media type 'application/json, application/x-www-form-urlencoded' in request.", "type": "error", "request_id": "1f3d91c9489247579c78e7ceaa5e67c8"}
Please help me.
Thank you
It looks like there is an issue with the spaces after your \ characters. If you try:
curl https://view-api.box.com/1/sessions \
-H "Authorization: Token APIKEY" \
-H "Content-Type: application/json" \
-d '{"document_id": "DOCID"}' \
-X POST
It should work.