-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add support for π Python objects to be updated in README
feat: Add support for π Python objects to be updated in README
- Loading branch information
Showing
7 changed files
with
332 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,19 +5,20 @@ | |
## **Code Embedder** | ||
Seamlessly update code snippets in your **README** files! πππ | ||
|
||
[Description](#-description) β’ [How it works](#-how-it-works) β’ [Examples](#-examples) β’ [Setup](#-setup) β’ [Under the hood](#-under-the-hood) | ||
[Description](#-description) β’ [How it works](#-how-it-works) β’ [Setup](#-setup) β’ [Examples](#-examples) β’ [Under the hood](#-under-the-hood) | ||
</div> | ||
|
||
|
||
## π Description | ||
|
||
**Code Embedder** is a GitHub Action that automatically updates code snippets in your markdown (`README`) files. It finds code blocks in your `README` that reference specific scripts, then replaces these blocks with the current content of those scripts. This keeps your documentation in sync with your code. | ||
|
||
β¨ **Key features** | ||
### β¨ Key features | ||
- π **Automatic synchronization**: Keep your `README` code examples up-to-date without manual intervention. | ||
- π **Section support**: Update specific sections of the script in the `README`. | ||
- π οΈ **Easy setup**: Simply add the action to your GitHub workflow and format your `README` code blocks. | ||
- π **Language agnostic**: Works with any programming language or file type. | ||
- π **Section support**: Update only specific sections of the script in the `README`. | ||
- 𧩠**Object support**: Update only specific objects (functions, classes) in the `README`. *The latest version supports only π Python objects (other languages to be added soon).* | ||
|
||
|
||
By using **Code Embedder**, you can focus on writing and updating your actual code π», while letting the action take care of keeping your documentation current ππ. This reduces the risk of outdated or incorrect code examples in your project documentation. | ||
|
||
|
@@ -43,9 +44,46 @@ You must also add the following comment tags in the script file `path/to/script` | |
... | ||
[Comment sign] code_embedder:section_name end | ||
``` | ||
The comment sign is the one that is used in the script file, e.g. `#` for Python, or `//` for JavaScript. The `section_name` must be unique in the file, otherwise the action will not be able to identify the section. | ||
The comment sign is the one that is used in the script file, e.g. `#` for Python, or `//` for JavaScript. The `section_name` must be unique in the file, otherwise the action will use the first section found. | ||
|
||
### 𧩠**Object** updates | ||
In the `README` (or other markdown) file, the object of the script is marked with the following tag: | ||
````md | ||
```language:path/to/script:object_name | ||
``` | ||
```` | ||
|
||
> [!Note] | ||
> The object name must match exactly the name of the object (function, class) in the script file. Currently, only π Python objects are supported. | ||
> [!Note] | ||
> If there is a section with the same name as any object, the object definition will be used in the `README` instead of the section. To avoid this, **use unique names for sections and objects!** | ||
## π§ Setup | ||
To use this action, you need to configure a yaml workflow file in `.github/workflows` folder (e.g. `.github/workflows/code-embedder.yaml`) with the following content: | ||
|
||
```yaml | ||
name: Code Embedder | ||
|
||
on: pull_request | ||
|
||
permissions: | ||
contents: write | ||
|
||
jobs: | ||
code_embedder: | ||
name: "Code embedder" | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
|
||
- name: Run code embedder | ||
uses: kvankova/[email protected] | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
``` | ||
|
||
## π‘ Examples | ||
|
||
|
@@ -112,34 +150,70 @@ print("Embedding successful") | |
|
||
With any changes to the section `A` in `main.py`, the code block section is updated in the `README` file with the next workflow run. | ||
|
||
## π§ Setup | ||
To use this action, you need to configure a yaml workflow file in `.github/workflows` folder (e.g. `.github/workflows/code-embedder.yaml`) with the following content: | ||
### 𧩠Object update | ||
The tag used for object update follows the same convention as the tag for section update, but you provide `object_name` instead of `section_name`. The object name can be a function name or a class name. | ||
|
||
```yaml | ||
name: Code Embedder | ||
> [!Note] | ||
> The `object_name` must match exactly the name of the object (function, class) in the script file, including the case. If you define class `Person` in the script, you must use `Person` as the object name in the `README`, not lowercase `person`. | ||
on: pull_request | ||
For example, let's say we have the following `README` file: | ||
````md | ||
# README | ||
|
||
permissions: | ||
contents: write | ||
This is a readme. | ||
|
||
jobs: | ||
code_embedder: | ||
name: "Code embedder" | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
Function `print_hello` is defined as follows: | ||
```python:main.py:print_hello | ||
``` | ||
|
||
- name: Run code embedder | ||
uses: kvankova/[email protected] | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
Class `Person` is defined as follows: | ||
```python:main.py:Person | ||
``` | ||
```` | ||
|
||
The `main.py` file contains the following code: | ||
```python | ||
... | ||
def print_hello(): | ||
print("Hello, world!") | ||
... | ||
|
||
class Person: | ||
def __init__(self, name): | ||
self.name = name | ||
def say_hello(self): | ||
print(f"Hello, {self.name}!") | ||
... | ||
``` | ||
|
||
Once the workflow runs, the code block section will be updated in the `README` file with the content of the function `print_hello` and class `Person` from the script located at `main.py` and pushed to the repository π. | ||
|
||
````md | ||
# README | ||
|
||
This is a readme. | ||
|
||
Function `print_hello` is defined as follows: | ||
```python:main.py:print_hello | ||
def print_hello(): | ||
print("Hello, world!") | ||
``` | ||
|
||
Class `Person` is defined as follows: | ||
```python:main.py:Person | ||
class Person: | ||
def __init__(self, name): | ||
self.name = name | ||
def say_hello(self): | ||
print(f"Hello, {self.name}!") | ||
``` | ||
```` | ||
|
||
With any changes to the function `print_hello` or class `Person` in `main.py`, the code block sections are updated in the `README` file with the next workflow run. | ||
|
||
|
||
## π¬ Under the hood | ||
This action performs the following steps: | ||
1. π Scans through the markdown (`README`) files to identify referenced script files (full script or section). | ||
1. π Scans through the markdown (`README`) files to identify referenced script files (full script, section or π Python object). | ||
1. π Extracts the contents from those script files and updates the corresponding code blocks in the markdown (`README`) files. | ||
1. π Commits and pushes the updated documentation back to the repository. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import re | ||
|
||
|
||
# Function verifying an email is valid | ||
def verify_email(email: str) -> bool: | ||
return re.match(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$", email) is not None | ||
|
||
|
||
class Person: | ||
def __init__(self, name: str, age: int): | ||
self.name = name | ||
self.age = age | ||
|
||
# String representation of the class | ||
def __str__(self) -> str: | ||
return f"Person(name={self.name}, age={self.age})" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# README 3 | ||
|
||
This is a test README file for testing the code embedding process. | ||
|
||
## Python objects | ||
|
||
This section contains examples of Python objects. | ||
|
||
```python:tests/data/example_python_objects.py:verify_email | ||
def verify_email(email: str) -> bool: | ||
return re.match(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$", email) is not None | ||
``` | ||
|
||
```python:tests/data/example_python_objects.py:Person | ||
class Person: | ||
def __init__(self, name: str, age: int): | ||
self.name = name | ||
self.age = age | ||
# String representation of the class | ||
def __str__(self) -> str: | ||
return f"Person(name={self.name}, age={self.age})" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# README 3 | ||
|
||
This is a test README file for testing the code embedding process. | ||
|
||
## Python objects | ||
|
||
This section contains examples of Python objects. | ||
|
||
```python:tests/data/example_python_objects.py:verify_email | ||
``` | ||
|
||
```python:tests/data/example_python_objects.py:Person | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.