Unicode in shell script to github API

33 Views Asked by At

I am trying to create labels using github api, but pass in emojis to the label name. Any ideas on how I can do this properly?

source config.txt

labels2=(
    "Sleep $zzz_unicode:FFFFFF"
)

# Read repository names from file
while IFS= read -r repo; do
    REPO_USER=$(echo "$repo" | cut -f1 -d /)
    REPO_NAME=$(echo "$repo" | cut -f2 -d /)

    echo "-----------------------------------------[$REPO_USER/$REPO_NAME]---------------------------------"

    # Iterate over labels
    for label in "${labels2[@]}"; do
        label_name=$(echo "$label" | cut -d ":" -f 1)
        label_color=$(echo "$label" | cut -d ":" -f 2)


        data="{\"name\":\"$label_name $emoji\",\"color\":\"$label_color\"}"
        response=$(curl -s -w "%{http_code}" -u "$token:x-oauth-basic" --request POST --data "$data" "https://api.github.com/repos/$REPO_USER/$REPO_NAME/labels")
        response_code=$(echo "$response" | tail -n1)
        response_body=$(echo "$response" | sed '$d')
        if [[ $response_code -eq 201 ]]; then
            echo "Label '$label_name $emoji' created successfully in repository '$REPO_USER/$REPO_NAME'"
        else
            echo "Failed to create label '$label_name $emoji' in repository '$REPO_USER/$REPO_NAME'. Response: $response_body"
        fi
    done

done < repo_names.txt

Tried using github unicode, as well as the actual emoji in label creation:

"Bug :FF0000"

"Sleep $zzz_unicode:FFFFFF"

I created a label manually on a repo: Bug with color FF0000. I can run a script to return all labels for that repo:

Fetching labels for Repo...
[
  {
    "id": someID,
    "node_id": "some_nodeID",
    "url": "https://api.github.com/repos/repo/labels/test%20%F0%9F%90%9B",
    "name": "test ",
    "color": "ff0000",
    "default": false,
    "description": ""
  }
]

But if I try using my script above to create the label for me using github API with the emoji in the label itself during creation: "Bug :FF0000" It creates label asBug ??

If I try creation with unicode: "Sleep $zzz_unicode:FFFFFF" it creates label as Sleep Note that sleep is just a test - zzz is github zzz emoji but should work the same.

2

There are 2 best solutions below

0
Madison Kennedy On BEST ANSWER

Github requires that you use their naming convention when submitting a request. Here is an example of my lables I wanted to implement:

labels=(
    "Bug :bug::FF0000"           # 
    "Feature :sparkles::00FF00"          # ✨
    "Documentation :books::0000FF" # 
)

And then just ensuring you are extracting label components properly when making your request.

label_name=$(echo "$label" | cut -d ":" -f 1)
label_emoji=$(echo "$label" | grep -oP ':[^:]+:')
label_color=$(echo "$label" | grep -oP '::\K.*$')

Here is an overview:

for label in "${labels[@]}"; do
        # Extract label components
        label_name=$(echo "$label" | cut -d ":" -f 1)
        label_emoji=$(echo "$label" | grep -oP ':[^:]+:')
        label_color=$(echo "$label" | grep -oP '::\K.*$')

        # Construct the label text with emoji shortcode
        label_text="\"name\":\"$label_name $label_emoji\""
        label_color="\"color\":\"$label_color\""

        # Print label text and color
        echo "{ $label_text, $label_color }"

        # Ensure proper color format (remove leading '#')
        label_color=$(echo "$label_color" | sed 's/^#//')

        # Prepare data for the POST request
        data="{ $label_text, $label_color }"  # Ensure proper color format

        # Send POST request to create label
        response=$(curl -s -w "%{http_code}" -u "$token:x-oauth-basic" --request POST --data "$data" "https://api.github.com/repos/$REPO_USER/$REPO_NAME/labels")
        response_code=$(echo "$response" | tail -n1)
        response_body=$(echo "$response" | sed '$d')
        if [[ $response_code -eq 201 ]]; then
            echo "Label '$label_name $label_emoji' created successfully in repository '$REPO_USER/$REPO_NAME'"
        else
            echo "Failed to create label '$label_name $label_emoji' in repository '$REPO_USER/$REPO_NAME'. Response: $response_body"
        fi
    done
    ```
2
Mark Reed On

If

  1. all your scripts are encoded in UTF-8, and
  2. your terminal supports it likewise, and
  3. you're running a modern version of Bash

(and by "modern", I mainly mean not the version 3.2 that ships in /bin on macOS)

... then Unicode characters should mostly Just Work. Here's a simple demonstration of bash acting Unicode-friendly:

$ printf '%X\n' "'"
1F4A4

As you can see, it recognizes the emoji as a single character and displays its code point when requested.

But many UNIX tools – like cut – are not so safe for multibyte text. I don't see where in your code you're setting the emoji variable that you use, but if you're doing any kind of parsing to get it the way you're doing for the repo and label, it could be giving you invalid results for that reason.

It might help to stick to bash builtins. For example, instead of this:

REPO_USER=$(echo "$repo" | cut -f1 -d /)
REPO_NAME=$(echo "$repo" | cut -f2 -d /)

you could do do this:

IFS=/ read REPO_USER REPO_NAME _ <<<"$repo"

(Although I don't know why you're naming those vars in all-caps; they don't appear to be being set as environment variables.)

If you could supply the whole program (minus auth keys or other sensitive data, of course), it might help.