loading...
Cover image for GitHub auto README with ruby, github-actions and dev.to API

GitHub auto README with ruby, github-actions and dev.to API

pashagray profile image Pavel Tkachenko ・4 min read

A brand new cool thing from github: you can create your own unique readme. And the ability to do this automatically is generally a gift for any software engineer. I'v read How I Built A Self-Updating README On My Github Profile article and it impressed me a lot. Thanks Michael! In this article Michael Hoffmann provided ready-to-use JS script, but this script parses his own site and doesn't use dev.to API. Also this article doesn't provide step-by-step guide for beginners. And finally, the biggest problem here is JS. Everyone loves ruby, not JS, it is an indisputable fact! That's what I want to fix.

Today we will be creating an automated README update with your recent posts from scratch using github-actions, ruby and dev.to API. At the end you will have a basic understanding of how github-actions works, how to use it properly with ruby (including gem installation) and how to handle secret ENV variables.

DEV.TO API

To work with API, we need to get API key. Go to https://dev.to/settings/account, find "DEV API Keys" section and generate your personal API key with any description you like (I called it "Auto update my GitHub Readme"). Keep it in secret please!

DEV.TO API key

Now you can go to DEV.TO API Documetation. There is a lot of cool stuff here. We need User published articles page. It allows you to fetch your published articles. That's what we are looking for! Let's check if API is working and key is valid. Open your terminal and paste:

curl -H "api-key: YOUR_API_KEY_HERE" https://dev.to/api/articles/me/published

If everything is ok, you will receive a JSON with all your published posts. We need title, url and description from this JSON.

Personal README

Open GitHub and create public repo with the same name as your GitHub account name. Don't forget to initialize README.md to let magic happen. You should see that your account page github.com/your_account/ has README with "Hi there 👋" message. Now you have basic README that you can edit, but we are going to automate this process.

GitHub Secrets

Now we need to provide our DEV.TO API key to GitHub environment. Open Settings tab in your_account_name/your_account_name/ and tap "Secrets" link. Add a new secret, name it DEV_TO_API_KEY and paste your API key as the value.

GitHub Secrets

Create you first script

Clone your repo. Add folders scripts/rb/ and create file update_readme.rb. We will use faraday gem to fetch posts from API. You can use ruby built-in NET::HTTP module, but I want you to show how to handle gem process installation with github actions.

# ./scripts/rb/update_readme.rb
require "json"
require "faraday"

# Get all posts
# Take a look how we obtain our secret key by using ENV[]
response = Faraday.get(
  "https://dev.to/api/articles/me/published",
  {},
  { "api-key": ENV["DEV_TO_API_KEY"] }
)

# Retrieve `title`, `url`, and `description` and
# wrap it to markdown syntax
posts = JSON.parse(response.body).map do |article|
  <<~EOF
  __[#{article['title']}](#{article['url']})__
  #{article['description']}
  EOF
end

# Generate your own layout and paste posts in it
# Don't forget to change text and name =)
markdown = <<~EOF
# Hello friends!
I'm a fullstack ruby and js developer. Follow me on [Dev.to](https://dev.to/pashagray)
My last publications:
#{posts.join}

Script is provided by https://github.com/pashagray
EOF

# Write you markdown to README.MD
File.write("./README.md", markdown)

That's all! git push all your changes back to GitHub.

GitHub Actions

Open Actions tab in your_account_name/your_account_name repo and create new workflow. There are a lot of templates, but you can initialize any or empty and paste code I provided below. Don't worry, every line has a comment.

# Name of your workflow
name: README Update
# Triggers to run workflow
on:
  # workflow_dispatch allows to run your workflow manually
  workflow_dispatch:
  # Run workflow based on specific schedule
  schedule:
  # This workflow will run every day at 00:00 UTC.
  # You can use https://crontab.guru/ if cron syntax is
  # looking weird for you
  - cron: "0 0 * * *"

jobs:
  # This workflow contains a single job called "perform"
  perform:
    # The type of runner that the job will run on
    # ubuntu-latest is default
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
    # This line to work properly with repo
    - uses: actions/checkout@v2
    # This one to activate ruby magic
    - uses: actions/setup-ruby@v1
      with:
        ruby-version: '2.7'
    # First we need to install Faraday gem. You can use ruby built-in NET::HTTP
    # class, but I want to show you how to work with gems in github-actions
    - name: Install gems
      run: gem install faraday
    # And now we run our script
    - name: Run script
      # Here we are setting our secret API Key
      # Details: https://docs.github.com/en/actions/configuring-and-managing-workflows/using-variables-and-secrets-in-a-workflow
      env:
        DEV_TO_API_KEY: ${{ secrets.DEV_TO_API_KEY }}
      run: ruby ./scripts/rb/update_readme.rb
    # Our script updated README.md, but we need to commit all changes
    - name: Commit and push if changed
      run: |
        git add .
        git diff
        git config --global user.email "github-action-bot@example.com"
        git config --global user.name "GitHub Action Bot"
        git commit -m "Updated README" -a || echo "No changes to commit"
        git push

Save your action and check it. Go to Actions, find your update README action and push "Run workflow" button.

Run workflow button

After workflow will be finished, go to your account page and enjoy it!

You can follow my repo and grab all ready to use code:
https://github.com/pashagray/pashagray

Discussion

pic
Editor guide
Collapse
elkhatibomar profile image
Omar

Hello I am not a ruby developer how I can pick random posts to show them like only 5 posts

Collapse
pashagray profile image
Pavel Tkachenko Author

The easiest way is to call sample(n) method on your posts where n is number of random posts you want to pick.

posts = JSON.parse(response.body).sample(5).map do |article|
Enter fullscreen mode Exit fullscreen mode

It works with any array.

[1, 2, 3, 4, 5].sample(3) #=> 3, 1, 5
[1, 2, 3, 4, 5].sample(3) #=> 5, 4, 1
[1, 2, 3, 4, 5].sample(3) #=> 2, 4, 3
Enter fullscreen mode Exit fullscreen mode
Collapse
elkhatibomar profile image
Omar

I will take it in consideration if I need to implement it , I edit it to get last post only with picture. Thanks for the script <3

Collapse
elkhatibomar profile image
Omar

I am trying to get the last post only with the picture.
I success with it :)
github.com/OmarElKhatibCS

Collapse
andrewmcodes profile image
Andrew Mason

Nice writeup! This gives me encouragement to go back and finish the api client gem I made for dev.to which would allow you to remove most of that script.