Editing GIST with cURL

#!/bin/bash

COMMIT=$(git log -1 --pretty=format:'{"subject": "%s", "name": "xxx", "date": "%cD"}')

curl -X PATCH -d'{"files": {"latest-commit": {"content": "$COMMIT"}}}' -u user:xxxx https://api.github.com/gists/xxx

This just shows $COMMIT in the Gist. I tried playing with ''' and stuff but cannot make this work.

Help?

Thanks!

1 answer

  • answered 2019-08-24 00:46 Léa Gris

    Your $COMMIT variable is not expanded to its value, because it is enclosed in single-quotes.

    Here are different methods you can employ to populate your request data with variable content:

    #!/bin/bash
    
    COMMIT="$(git log -1 --pretty='format:{"subject": "%s", "name": "xxx", "date": "%cD"}')"
    
    # use printf in sub-shell to insert the value of $COMMIT into the proper place in the JSON
    curl -X PATCH -d "$(printf '{"files": {"latest-commit": {"content": %s}}}' "$COMMIT"
    )" -u user:xxxx https://api.github.com/gists/xxx
    

    Or fully integrated into the curl call:

    #!/usr/bin/env bash
    
    # use printf in sub-shell to dynamically insert the value
    # into the proper place in the JSON data
    # for the PATCH request
    curl \
      --request PATCH \
      --data "$(
        printf '{"files": {"latest-commit": {"content": %s}}}' \
          "$(
            git log -1 --pretty='format:{"subject": "%s", "name": "xxx", "date": "%cD"}'
          )"
      )" \
      --user user:xxxx \
      https://api.github.com/gists/xxx
    

    And another cleaner, detailed and hopefully more correct implementation:

    #!/usr/bin/env bash
    
    # Set to the gist id to update
    gist_id='xxx'
    
    # Uncomment and set to your GitHub API OAUTH token
    #github_oauth_token="xxxxxxxxxxxxxxxxxx"
    
    # Or uncomment this and set to your GitHub username:password
    #github_user="user:xxxx"
    
    github_api='https://api.github.com'
    
    # create a template for the latest-commit.json file content
    # from this raw here-document without variable expansion
    read -r -d '' latest_commit_template <<'EOF'
    {
      "subject": "%s",
      "name": "%aN",
      "date": "%cD"
    }
    EOF
    
    # populate the latest-commit.json file content from its template
    latest_commit_json_content="$(
      git log \
        -1 \
        --pretty="format:$latest_commit_template"
    )"
    
    # compose the GitHub API JSON data payload
    # to update the latest-commit.json file in the $gist_id
    # that expands the $latest_commit_json_content variable
    read -r -d '' json_data_payload <<EOF
    {
      "files": {
        "latest-commit.json": {
          "filename": "latest-commit.json",
          "content": "$latest_commit_json_content"
        }
      }
    }
    EOF
    
    # compact patch data JSON before transmission
    # comment this if you don't have jq installed
    json_data_payload="$(
      jq \
        --compact-output \
        '.' \
        <<<"$json_data_payload"
    )"
    
    # prepare the curl call with options for the GitHub API request
    github_api_request=(
      curl # The command to send the request
      --header "Content-Type: application/json" # The MIME type of the request  
      --request PATCH # The request type
      --data "$json_data_payload" # The payload content of the request
    )
    
    if [ -n "$github_oauth_token" ]; then
      github_api_request+=(
        # Authenticate the GitHub API with a OAUTH token
        --header "Authorization: token $github_oauth_token"
      )
    elif [ -n "$github_user" ]; then
      github_api_request+=(
        # Authenticate the GitHub API with an HTTP auth user:pass
        --user "$github_user"
      )
    else
      echo 'GitHub API require either an OAUTH token or a user:pass' >&2
      exit 1
    fi
    
    github_api_request+=(
      -- # End of curl options
      "$github_api/gists/$gist_id" # The GitHub API url to address the request
    )
    
    # perform the GitHub API request call
    "${github_api_request[@]}"```