diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..260d8f9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM ruby:3.3 + +COPY . /app +WORKDIR /app + +ENTRYPOINT ["ruby", "/app/winget.rb"] diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..ea6be1b --- /dev/null +++ b/action.yml @@ -0,0 +1,57 @@ +name: "Winget Badge Update" +description: "Showcase your number of merged pull requests in profile's README dynamically" +author: "Naveen Prashanth @gnpaone" +inputs: + id: + description: "Winget package ID" + required: true + style: + description: "Badge style" # accepted values: flat, flat-square, plastic, for-the-badge, social + default: "flat" + required: false + label: + description: "Left-hand-side text" + default: "Winget package" + required: false + label_color: + description: "Background color of the left part" + default: "gray" + required: false + color: + description: "Background color of the right part" + default: "blue" + required: false + readme_path: + description: "Path of readme file" + default: "./README.md" + required: false + marker_text: + description: "Marker text to replace in readme file" + required: true + pkg_link: + description: "Winget package repo link" + default: "" + required: false + commit_user: + description: "Git username" + default: "winget-badge-bot" + required: false + commit_email: + description: "Git user email" + default: "winget-badge-actions[bot]@github.com" + required: false + commit_message: + description: "Git commit message" + default: "Update readme with latest winget version badge" + required: false +outputs: + winget_ver: + description: "Winget package version" + +runs: + using: "docker" + image: "Dockerfile" + +branding: + icon: 'tag' + color: 'purple' diff --git a/examples/basic.yml b/examples/basic.yml new file mode 100644 index 0000000..9bac720 --- /dev/null +++ b/examples/basic.yml @@ -0,0 +1,20 @@ +name: Winget badge update + +on: + release: + types: [published] # runs after each package published + workflow_dispatch: # run on workflow dispatch + +jobs: + update-badge: + name: Update latest version + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Winget Version Badge + uses: gnpaone/winget-badge@main + with: + id: "Git.Git" + marker_text: "TEST_PKG" diff --git a/examples/multi-ver.yml b/examples/multi-ver.yml new file mode 100644 index 0000000..c288ffb --- /dev/null +++ b/examples/multi-ver.yml @@ -0,0 +1,35 @@ +name: Multiple badges update + +on: + release: + types: [published] + workflow_dispatch: + +jobs: + update-badge: + name: Update latest version + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Winget Version Badge + uses: gnpaone/winget-badge@latest + with: + id: "GitHub.cli,Git.Git" + marker_text: "TEST_PKG_1,TEST_PKG_2" + pkg_link: "https://github.com," + label: "Winget package" + label_color: ",red" + color: "blue,green" + id: latestver + + - name: Version + run: | + version=${{ steps.latestver.outputs.winget_ver }} + echo "ver=$version" >> $GITHUB_OUTPUT + IFS=',' read -r -a array <<< "$version" + for i in "${!array[@]}"; do + echo "ver$i=${array[$i]}" >> $GITHUB_OUTPUT + done + \ No newline at end of file diff --git a/winget.rb b/winget.rb new file mode 100644 index 0000000..74a649a --- /dev/null +++ b/winget.rb @@ -0,0 +1,113 @@ +# frozen_string_literal: true + +require 'net/http' +require 'erb' +require 'open-uri' + +class Winget + def run + id = ENV['INPUT_ID'] + style = ENV['INPUT_STYLE'] + label = ENV['INPUT_LABEL'] || 'Winget package' + labelColor = ENV['INPUT_LABEL_COLOR'] + color = ENV['INPUT_COLOR'] + readme_path = ENV['INPUT_README_PATH'] + marker_text = ENV['INPUT_MARKER_TEXT'] + pkg_link = ENV['INPUT_PKG_LINK'] + git_username = ENV['INPUT_COMMIT_USER'] + git_email = ENV['INPUT_COMMIT_EMAIL'] + commit_message = ENV['INPUT_COMMIT_MESSAGE'] || 'Update README.md' + + fetch_winget(id, style, label, labelColor, color, marker_text, pkg_link, readme_path, commit_message, git_username, git_email) + rescue StandardError => e + puts "Error: #{e.message}" + exit 1 + end + + private + + def fetch_winget(id, style, label, labelColor, color, marker_text, pkg_link, readme_path, commit_message, git_username, git_email) + id_array = id.split(',') + marker_text_array = marker_text.split(',') + + if id_array.length != marker_text_array.length + puts "Error: 'id' and 'marker_text' must have the same array length." + exit 1 + end + + def handle_param_array(param, id_length, param_name) + param_array = param.split(',') + if param_array.length == 1 + Array.new(id_length, param_array[0]) + elsif param_array.length == id_length + param_array + else + puts "Error: '#{param_name}' must have an array length of 1 or equal to 'id' array length." + exit 1 + end + end + + style_array = handle_param_array(style, id_array.length, 'style') + label_array = handle_param_array(label, id_array.length, 'label') + labelColor_array = handle_param_array(labelColor, id_array.length, 'labelColor') + color_array = handle_param_array(color, id_array.length, 'color') + readme_path_array = handle_param_array(readme_path, id_array.length, 'readme_path') + pkg_link_array = handle_param_array(pkg_link, id_array.length, 'pkg_link') + + winget_ver_array = Array.new(id_array.length) + + id_array.length.times do |i| + api_url = "https://winget-version-badge.vercel.app/?id=#{id_array[i]}" + uri = URI(api_url) + req = Net::HTTP::Get.new(uri) + + response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| + http.request(req) + end + + if response.is_a?(Net::HTTPSuccess) + pkg_ver = URI.open(api_url).read + winget_ver_array[i] = pkg_ver + + update_readme_content(id_array[i], style_array[i], label_array[i], labelColor_array[i], color_array[i], marker_text_array[i], pkg_link_array[i], readme_path_array[i], pkg_ver) + else + puts "Failed to retrieve: #{id_array[i]} - #{response.code} - #{response.message}" + exit 1 + end + end + + winget_ver = winget_ver_array.join(',') + + File.open(ENV['GITHUB_OUTPUT'], 'a') do |file| + file.puts("winget_ver=#{winget_ver}") + end + + update_git_repo(readme_path, commit_message, git_username, git_email) + end + + def update_readme_content(id, style, label, labelColor, color, marker_text, pkg_link, readme_path, winget_ver) + readme_content = File.read(readme_path) + start_marker = "" + end_marker = "" + shields_url = "https://img.shields.io/badge/#{ERB::Util.url_encode(label)}-#{winget_ver}-#{color}?style=#{style}&labelColor=#{labelColor}" + + updated_readme_content = readme_content.gsub(/#{start_marker}.*#{end_marker}/m, "#{start_marker}[![#{id}](#{shields_url})](#{pkg_link})#{end_marker}") + + File.write(readme_path, updated_readme_content) + end + + def update_git_repo(readme_path, commit_message, git_username, git_email) + `git config --global --add safe.directory /github/workspace` + `git config user.name #{git_username}` + `git config user.email #{git_email}` + + status = `git status` + unless status.include?("nothing to commit") + `git add #{readme_path}` + `git commit -m "#{commit_message}"` + `git push` + end + end +end + +Winget.new.run \ No newline at end of file