PythonKiddieScripterX
PythonKiddieScripterX

Reputation: 517

Can github actions edit parts of README.md?

I want to update ONLY the first header of a readme so it always has the repo's name. I know how to get the repo name in github actions by doing something like:

name: CI

on:
 push:

jobs:
 build:
 runs-on: ubuntu-latest

 steps:
      - uses: actions/checkout@v3

      - name: Run a one-line script
 run: echo "REPO_NAME=${{ github.event.repository.name }}" >> $GITHUB_ENV

However, I want to access my readme.md and add the 'github.event.repository.name' to the header. So I would make a Readme with something like:

Introduction for: {{ github.event.repository.name }}

hoping I can get something like this with gitactions:

Introduction for: RepoName

I tried using some marketplace github actions but the one I tried seems to not do variables and it seems to update the whole readme.md not just the header: https://github.com/marketplace/actions/dynamic-readme

Here is the failed example for this marketplace plugin:

name: Dynamic Template

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  update_templates:
    name: "Update Templates"
    runs-on: ubuntu-latest
    steps:
      - name: "📥  Fetching Repository Contents"
        uses: actions/checkout@main

      # Runs a single command using the runners shell
      - name: Run a one-line script
        run: echo "REPO_NAME=${{ github.event.repository.name }}" >> $GITHUB_ENV


      # Runs a set of commands using the runners shell
      - name: Update GitHub Profile README
        uses: theboi/[email protected]
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          REPO_NAME: ${{ github.event.repository.name }}
        with:
          header: $REPO_NAME

Is there any way to make the readme.md file have the repo name dynamically with a variable in github actions?

EDIT: I think I am very close but I don't know how to commit code in github actions. I figured, I can do this manually by using the sed command in bash in github actions. I think it worked but I think I have to commit the code to make it save. Here is the code I have so far:

name: Dynamic Template

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  update_templates:
    name: "Update Templates"
    runs-on: ubuntu-latest
    steps:
      - name: "📥  Fetching Repository Contents"
        uses: actions/checkout@main

      # Runs a single command using the runners shell
      - name: Run a one-line script
        run: echo "REPO_NAME=${{ github.event.repository.name }}" >> $GITHUB_ENV


      # Runs a set of commands using the runners shell
      - name: Run a multi-line script
        run: |
          ls
          sed -i 's/<reponame>/$REPO_NAME/' README.md
          cat README.md
          echo $REPO_NAME

Upvotes: 5

Views: 4627

Answers (2)

xihajun
xihajun

Reputation: 77

This method needs four files

  • README.md
  • python script #replace tag
  • github_action.yml #run it automatically
  • variable.json #define variable

@PythonKiddieScripterX provides a good idea.

Based on the idea that context inside <> those <information will be hidden>. We can update our readme files by replacing those tags <> with the texts we want.

Example of my README.md file

This answer is version `1.0`. It will be updated automatically by loading `json` file and using GitHub Action.

In my readme.json file

{
  VERSION: 1.0
}

Then I will only need a script to do the replacement. In this example, I use python saved as

replace_tag.py.

import re
import os
import json

# read all .md files
readmefiles = []
for root, dirs, files in os.walk("."):
    for file in files:
        if file.endswith(".md"):
             readmefiles.append(os.path.join(root, file))

# load variable json
with open('readme.json') as f:
  var_dic = json.load(f)

# match pattern (<variable-*.?-tag>)(`*.?`)
# example: (<variable-VERSION-tag>)(`1.1`)
for filename in readmefiles:
    with open(filename,"r") as f:
      content = f.read()
    
    # update readme variables
    for key, value in var_dic.items():
      pattern = r"(<variable-{}-tag>)(`.*?`)".format(key)
      replacement = r"\1`{}`".format(value)
      content = re.sub(pattern, replacement, content)

    with open(filename,"w") as f:
      f.write(content)

Then the final thing is to use GitHub Action to run this python script every time there is a change.

yml file could be

name: README Dynamic Update

on:
  push:
    paths:
      - *.md
      - readme.json
      - **/*.md
  workflow_dispatch:

jobs:
  update_templates:
    name: "Update Templates"
    runs-on: ubuntu-latest
    steps:
      - name: "📥 Update GitHub Readme files"
        uses: actions/checkout@main

      # Runs a set of commands using the runners shell
      - name: Update README.md
        run: |
          python replace_tag.py

      - name: pull-request
        uses: repo-sync/pull-request@v2
        with:
          destination_branch: "main"
          github_token: ${{ secrets.GITHUB_TOKEN }}

      - name: commit
        run: |
          git config --global user.email youremail
          git config --global user.name yourusername
          git add .
          git commit -m "README update Automation" -a
      - name: Push changes
        uses: ad-m/github-push-action@master
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}

Also for those text inside the code blocks, we can use <pre></pre> to solve the hidding issue.

Note that

  • need to add tag in this format <variable-YOURTAG-tag>"variable"

Upvotes: 1

PythonKiddieScripterX
PythonKiddieScripterX

Reputation: 517

I figured it out. You can it manually by using the sed command in bash within a runner in github actions. Set your README.md with a variable that you want to replace like <reponame> then use github actions to find that string and replace it with something you want (for me the repo name).

name: Dynamic Template

on:
  create:

jobs:
  update_templates:
    name: "Update Templates"
    runs-on: ubuntu-latest
    steps:
      - name: "📥  Fetching Repository Contents"
        uses: actions/checkout@main

      # Runs a set of commands using the runners shell
      - name: Update README.md
        run: |
          sed -i 's/<reponame>/'${{ github.event.repository.name }}'/' README.md
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git config user.name "github-actions[bot]"
          git commit -am "Automated report"
          git push

The email I used is a dependabot mentioned from here: https://github.com/orgs/community/discussions/26560#discussioncomment-3531273

Upvotes: 5

Related Questions