Tag: GitHub

  • Automating Markdown Management: Scripts for Consolidating Documentation on GitHub

    Automating Markdown Management: Scripts for Consolidating Documentation on GitHub

    The scripts discussed in this blog aim to automate the process of retrieving, combining, and updating Markdown files in a GitHub repository. Markdown is a lightweight markup language with plain text formatting syntax, and it’s commonly used for creating formatted text on the web. These scripts are particularly useful for documentation or projects that require a compilation of various Markdown documents into a single, cohesive file.

    Here is a breakdown of the overarching goals of the scripts:

    Retrieve Markdown Files from GitHub: The first part of the scripts involves connecting to the GitHub repository using the GitHub API. The objective is to fetch a list of all the Markdown (.md) files available in the repository. This step takes into account the structure and naming conventions of the files, retrieving them in a sorted order, with README.md often being the initial file as it usually serves as the entry point or introduction to the repository.

    Combine Markdown Files: Once the list of Markdown files is retrieved, the scripts download the content of each file. These contents are then combined into a single Markdown document. This combination process may involve cleaning up or reformatting headings and other elements to ensure that the single document maintains readability and a logical structure after the merge.

    Push Combined File Back to GitHub: After creating a single, combined Markdown document, the scripts then push this new document back to the original GitHub repository. This step may include creating a new file or updating an existing one with the combined content. The operation involves committing the changes to the repository, which keeps a record of the update and allows for version control.

    Automation and Efficiency: The entire process is automated using Python or PowerShell scripts. This automation is designed to save time and reduce the risk of human error that can occur with manual combining and updating of documentation files. It is particularly useful for projects that regularly update their documentation or have multiple contributors, as it ensures that the latest information is always compiled and available in a single, updated document.

    These scripts are flexible and can be customized to suit specific project needs, such as sorting files in a particular order, handling different file hierarchies, or dealing with complex document structures. The use of these scripts exemplifies how programming can be utilized to streamline workflow processes, enhance collaboration, and maintain organized and up-to-date documentation in software development projects.

    Join Markdown

    This a script that concatenates multiple Markdown files into a single file, it requires some steps to ensure the headings and other elements are adjusted appropriately to maintain the document structure.

    Below is a Python script that does the following:

    • Takes a list of Markdown filenames.
    • Adjusts their heading levels to maintain structure.
    • Concatenates them into a single Markdown file.
    import re
    
    def adjust_headings(text, level_increase=1):
        """
        Adjust the heading levels in the given markdown text.
        """
        def replace_func(match):
            return '#' * (len(match.group(0)) + level_increase)
    
        # This regex matches markdown headings
        return re.sub(r'^(#{1,6})', replace_func, text, flags=re.MULTILINE)
    
    def concatenate_markdown_files(filenames, output_filename='combined.md'):
        """
        Concatenate a list of markdown files into a single file with adjusted headings.
        """
        with open(output_filename, 'w') as outfile:
            for filename in filenames:
                with open(filename, 'r') as infile:
                    text = infile.read()
                    # Increase heading levels by 1 (or desired amount)
                    adjusted_text = adjust_headings(text, 1)
                    outfile.write(adjusted_text + '\n\n')
    
    # List of markdown files to concatenate
    markdown_files = ['file1.md', 'file2.md', 'file3.md']
    
    # Output file name
    output_file = 'combined.md'
    
    # Concatenate files
    concatenate_markdown_files(markdown_files, output_file)
    
    print(f'Concatenated Markdown written to {output_file}')
    
    

    Using the GitHub API – Python

    Retrieving a list of Markdown files from a GitHub repository can be done using the GitHub API. Below is a Python script example that uses the requests library to call the GitHub API and retrieve a list of all Markdown .md files from a specified repository:

    • Retrieves the list of Markdown files from a specified GitHub repository.
    • Downloads the contents of these files.
    • Concatenates them into a single Markdown file, making sure README.md (if present) is first.
    • Commits and pushes the single Markdown file back to the GitHub repository.

    If you’re planning on using this script frequently or with private repositories, you should authenticate your requests using a personal access token. You can add the token to your request like this:

    headers = {'Authorization': 'token YOUR_TOKEN'}
    response = requests.get(api_url, headers=headers)
    

    To do this, you’ll need a GitHub Personal Access Token with the appropriate permissions to access repositories, read their contents, and push changes. See managing-your-personal-access-tokens

    you will need to install requests

    pip install requests
    

    Here’s an outline of the script:

    import requests
    from requests.auth import HTTPBasicAuth
    import base64
    import re
    
    # Constants for GitHub API headers, including the authorization token.
    # Note: The token should be kept secret and not hardcoded in the code. Use environment variables for production.
    headers = {
        'Accept': 'application/vnd.github.v3+json',
        'Authorization': 'token <YOUR_GITHUB_TOKEN>'
    }
    
    def get_repo_contents(user, repo, path=''):
        """
        Get the contents of a repository at a specified path.
    
        :param user: GitHub username
        :param repo: GitHub repository name
        :param path: path inside the repository (optional, default is root)
        :return: JSON response with repository contents
        """
        api_url = f"https://api.github.com/repos/{user}/{repo}/contents/{path}"
        response = requests.get(api_url, headers=headers)
        response.raise_for_status()
        return response.json()
    
    def get_markdown_files(repo_contents):
        """
        Filter and sort the list of files in the repository to get Markdown files.
    
        :param repo_contents: JSON response with repository contents
        :return: List of sorted Markdown files, excluding README.md
        """
        return sorted([file for file in repo_contents if file['name'].endswith('.md')], key=lambda x: (x['name'] != 'README.md', x['name']))
    
    def download_files(files_info):
        """
        Download the content of each file in the list of files.
    
        :param files_info: List of file information, which includes the download URL
        :return: List of contents of each Markdown file
        """
        md_contents = []
        for file_info in files_info:
            download_url = file_info['download_url']
            response = requests.get(download_url)
            response.raise_for_status()
            md_contents.append(response.text)
        return md_contents
    
    def combine_markdown(md_files_contents):
        """
        Combine the content of all Markdown files into a single string.
    
        :param md_files_contents: List of contents of each Markdown file
        :return: A single string containing all combined Markdown content
        """
        combined_md = '\n\n'.join(md_files_contents)
        return combined_md
    
    def push_to_github(user, repo, path, content, commit_message):
        """
        Push a file's content to GitHub repository.
    
        :param user: GitHub username
        :param repo: GitHub repository name
        :param path: Path where the file will be pushed
        :param content: Content to be pushed
        :param commit_message: Commit message
        :return: JSON response from the GitHub API
        """
        api_url = f"https://api.github.com/repos/{user}/{repo}/contents/{path}"
        get_response = requests.get(api_url, headers=headers)
    
        # If file exists, use its SHA to update, else create a new file
        sha = get_response.json().get('sha') if get_response.status_code == 200 else None
    
        # Encode content to base64 as required by GitHub API
        base64content = base64.b64encode(content.encode('utf-8')).decode('utf-8')
    
        # Prepare data payload for the PUT request
        data = {
            "message": commit_message,
            "committer": {
                "name": "Your Name",
                "email": "your.email@example.com"
            },
            "content": base64content,
            "sha": sha
        }
    
        # If creating a new file, the 'sha' field should not be included
        if not sha:
            del data["sha"]
    
        # Make the PUT request to GitHub API
        response = requests.put(api_url, headers=headers, json=data)
        response.raise_for_status()
        return response.json()
    
    # Main process
    github_user = 'mygithubusername'
    github_repo = 'mygithubreponame'
    github_path = ''
    output_file_path = 'combined.md'
    commit_message = 'Update combined markdown file'
    
    try:
        # Step 1: Get the list of Markdown files from the repository
        contents = get_repo_contents(github_user, github_repo, github_path)
        markdown_files_info = get_markdown_files(contents)
        
        # Step 2: Download the content of Markdown files
        markdown_files_contents = download_files(markdown_files_info)
        
        # Step 3: Combine the downloaded Markdown content into a single document
        combined_md = combine_markdown(markdown_files_contents)
        
        # Step 4: Push the combined Markdown content back to GitHub
        push_result = push_to_github(github_user, github_repo, output_file_path, combined_md, commit_message)
        print(f"Successfully pushed to {push_result['content']['html_url']}")
    except requests.HTTPError as http_err:
        # If an HTTP error occurs, print
    
    

    Replace YOUR_GITHUB_TOKEN with your actual GitHub token, username with the GitHub username or organization name, repository with the repository name, and adjust Your Name and your.email@example.com with your details.

    Note that this script is quite basic and assumes:

    • All the Markdown files are in the root of the repository.
    • The README.md is in the root and will be the first file.
    • You have the necessary permissions to push to the repository.
    • You would also need to handle API rate limits and pagination for repositories with many files.

    Please ensure you understand the implications of using your Personal Access Token in scripts, and secure it appropriately.

    In a production environment, you would want to use environment variables or a configuration file to store sensitive information like API tokens.

    Using the GitHub API – PowerShell

    Here is an example of how you could achieve the same task using PowerShell. Please ensure you have the correct permissions and your GitHub personal access token ready to use.

    Do not share your token in your scripts or store it in a public place.

    
    # Set your GitHub username and repository
    $user = "yourusername"
    $repo = "yourrepo"
    
    # Set the GitHub API token as an environment variable for security
    $env:GITHUB_TOKEN = "<YOUR_GITHUB_TOKEN>"
    
    # Base64 encode the GitHub token for authorization
    $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$env:GITHUB_TOKEN)))
    
    # Function to retrieve the list of markdown files from GitHub repository
    function Get-MarkdownFilesFromRepo {
        param (
            [string]$User,
            [string]$Repository
        )
    
        $headers = @{
            Authorization=("Basic {0}" -f $base64AuthInfo)
            Accept="application/vnd.github.v3.raw"
        }
    
        $apiUrl = "https://api.github.com/repos/$User/$Repository/git/trees/main?recursive=1"
        $response = Invoke-RestMethod -Uri $apiUrl -Method Get -Headers $headers
    
        # Filter out markdown files and return their paths
        return $response.tree | Where-Object { $_.path -like '*.md' } | Sort-Object path
    }
    
    # Function to download the content of markdown files
    function Get-ContentFromMarkdownFiles {
        param (
            [object[]]$MarkdownFiles
        )
    
        $headers = @{
            Authorization=("Basic {0}" -f $base64AuthInfo)
            Accept="application/vnd.github.v3.raw"
        }
    
        $contentList = @()
    
        foreach ($file in $MarkdownFiles) {
            $fileResponse = Invoke-RestMethod -Uri $file.url -Method Get -Headers $headers
            $contentList += $fileResponse
        }
    
        return $contentList
    }
    
    # Function to update or create a markdown file in the repository
    function Update-GithubMarkdownFile {
        param (
            [string]$User,
            [string]$Repository,
            [string]$FilePath,
            [string]$Content,
            [string]$Message
        )
    
        $headers = @{
            Authorization=("Basic {0}" -f $base64AuthInfo)
            Accept="application/vnd.github.v3+json"
        }
    
        $body = @{
            message = $Message
            content = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($Content))
            # If updating an existing file, 'sha' of the file should be included in the body
            # sha = <SHA_OF_THE_FILE_TO_UPDATE>
        } | ConvertTo-Json
    
        $apiUrl = "https://api.github.com/repos/$User/$Repository/contents/$FilePath"
        $response = Invoke-RestMethod -Uri $apiUrl -Method Put -Body $body -Headers $headers -ContentType "application/json"
    
        return $response
    }
    
    # Main process
    try {
        $markdownFiles = Get-MarkdownFilesFromRepo -User $user -Repository $repo
        $markdownContent = Get-ContentFromMarkdownFiles -MarkdownFiles $markdownFiles
        $combinedContent = $markdownContent -join "`n`n"
        $updateResponse = Update-GithubMarkdownFile -User $user -Repository $repo -FilePath "combined.md" -Content $combinedContent -Message "Combine markdown files"
        Write-Host "Successfully updated file: $($updateResponse.content.html_url)"
    }
    catch {
        Write-Error "An error occurred: $_"
    }
    
    

    Make sure to replace <YOUR_GITHUB_TOKEN> with your actual GitHub token.

    This script follows a similar structure to the Python script but adapted to PowerShell:

    • Get-MarkdownFilesFromRepo: Retrieves a list of markdown files from the specified GitHub repository.
    • Get-ContentFromMarkdownFiles: Downloads the content of each markdown file.
    • Update-GithubMarkdownFile: Pushes the combined markdown content back to GitHub. If updating an existing file, you will need to retrieve the file’s SHA and include it in the request body.
    • The main process then executes these functions, combines the content of markdown files, and pushes the combined content to the GitHub repository.

    Handling 404 Errors

    A 404 Not Found error when trying to access the GitHub API usually means that the URL is incorrect or the resource doesn’t exist. Here are some possible reasons and solutions:

    Incorrect Repository Name/User: Ensure that the user (yourusername) and repository (yourrepo) names are spelled correctly, and that the repository actually exists and is public. If it’s a private repository, make sure your token has the right permissions.

    API Rate Limiting: If you’re not using a token or your token doesn’t have the correct permissions, GitHub API usage is quite limited. Check if you’ve hit the rate limit.

    Branch Name: By default, GitHub repositories now name their primary branch main instead of master. If you have specified the branch name in the API call and the repository’s primary branch has a different name, it will lead to a 404 error.

    Access Token Permissions: If the repository is private, make sure that your GitHub token has the repo scope to access private repositories.

    Before executing the main process, check if the repository exists by visiting https://github.com/yourusername/yourrepo. If the repository exists, ensure the path you are trying to access (contents/) is correct.

    If you have confirmed that the repository and user names are correct, and the repository is public, the next step is to make sure that your access token is correct and has the necessary permissions. Double-check the token, and if it’s a private repository, make sure you’ve given the token the appropriate scope.

    Finally, if you are sure the repository exists and your token is correctly set up, check the branch name in the function get_repo_contents in the branch=’main’ parameter. If the repository uses a different default branch name, you’ll need to specify that name.

    Once you’ve checked all the above, try to run the script again. If you’re still encountering issues, you may want to run a curl command or use Postman to manually check the API response before executing it in the script. Here’s a curl example to test access to the repository:

    curl -H "Authorization: token YOUR_GITHUB_TOKEN" \
         -H "Accept: application/vnd.github.v3+json" \
         "https://api.github.com/repos/yourusername/yourrepo/contents/"
    
    

    Make sure to replace YOUR_GITHUB_TOKEN with your actual token. If the curl command works but your script does not, you’ll need to troubleshoot the script further. If the curl command also fails, then the issue may lie with the repository access settings or the token permissions.

    In the following check script:

    • The script sends an HTTP GET request to the GitHub API.
    • If successful, it will list the file paths in the repository’s root directory.
    • If there’s an error (like a 404), it will display the status code, status description, and error message.
    • The headers are passed as a hashtable to the -Headers parameter.
    • The User-Agent header is included in the hashtable.
    • The personal access token should replace YOUR_GITHUB_TOKEN in the Authorization field.
    
    $Headers = @{
        Authorization = "token YOUR_GITHUB_TOKEN"
        Accept = "application/vnd.github.v3+json"
    }
    
    $Uri = "https://api.github.com/repos/yourusername/yourepo/contents/"
    
    try {
        $Response = Invoke-WebRequest -Uri $Uri -Headers $Headers -Method Get
        $Content = $Response.Content
        $RepositoryContent = $Content | ConvertFrom-Json
        foreach ($File in $RepositoryContent) {
            Write-Host "File Path: $($File.path)"
        }
    } catch {
        Write-Error $_.Exception.Response.StatusCode.Value__
        Write-Error $_.Exception.Response.StatusDescription
        Write-Error $_.Exception.Message
    }
    
    

    If you are still encountering the 404 error, you should:

    • Check that the GitHub token is correct and has the proper scopes enabled.
    • Ensure the repository yourusername/yourrepo is indeed public. If the repository is private, ensure your GitHub token has the repo scope to access private repositories.

    Run this script in your PowerShell console after replacing YOUR_GITHUB_TOKEN with the actual token value. If it is successful, it will print out the file paths of the contents in the repository. If there’s an error, it will print out more detailed error information which can help in further troubleshooting.

  • Automating GitHub to WordPress

    Automating GitHub to WordPress

    I am using the built-in WordPress.com editor to create my posts and then manually copying and pasting your markdown content into the editor. While this may not be as efficient as an automation using a plugin, it still allow me to easily format and publish my blog posts using markdown syntax. But, to be honest, it takes to long and i need to step up my production rate.

    Automating the publishing of my blog posts from GitHub to WordPress would be a time-saving and efficient process. There are a few different ways you I achieve this, depending on how I my prioritise my needs and characterise my preferences.

    Whichever approach I choose, automating the publishing process should save me time and streamline my workflow.

    Automation

    One approach would to take is to use a plugin like WP GitHuber MD, which would allows me to connect to my GitHub account to my WordPress site and automatically publish markdown files as blog posts.

    With this plugin, i could customize settings such as the post title, tags, and categories, as well as the formatting of markdown content.

    Just need be sure to test the setup thoroughly and monitor posts to make sure they’re appearing correctly on the WordPress site.

    WP GitHuber MD is a WordPress plugin that allows you to publish blog posts from markdown files stored in a GitHub repository. It was created by Kellen Mace and is available for free on the WordPress plugin repository.

    Here are the high level steps to set up WP GitHuber MD:

    1. Install and activate the plugin on your WordPress site.
    2. Go to the plugin’s settings page and connect the GitHub account.
    3. Choose the repository and branch to use for your blog posts.
    4. Customize the settings for posts, such as the post title and tags.
    5. Create a new markdown file in the GitHub repository, using the filename format “YYYY-MM-DD-post-title.md” (for example, “2023-05-14-automating-publishing-to-wordpress.md”).
    6. Add your markdown content to the file, using the plugin’s syntax to specify post metadata like title, tags, and categories.
    7. Commit and push the changes to GitHub.
    8. The plugin will automatically detect the new markdown file and publish it as a blog post on the WordPress site.

    To test the integration, I can create a new markdown file in your GitHub repository and verify that it appears as a new post on my WordPress site.

    You can also test the plugin’s customization settings by adjusting the post title, tags, and formatting in the markdown file and checking that they are applied correctly when the post is published.

    If I run into any issues or have questions about using WP GitHuber MD, it looks like I can find support on the WordPress plugin repository page or by contacting the plugin’s developer directly.

    I should, of courses, read the plugin’s documentation and FAQs to troubleshoot common issues and learn more about its features and capabilities.

    Here are some links related to WP GitHuber MD:

    But, unfortunately, WP GitHuber MD does not work with WordPress.com free accounts as it requires certain server-side permissions that may not be available on the free plan. WordPress.com does not allow the installation of third-party plugins on free plans, which means you may not be able to use WP GitHuber MD to publish your blog posts from GitHub.

    A paid WordPress.com plan, such as the Business or eCommerce plan, has more options available for automating your publishing workflow, including the use of third-party plugins like WP GitHuber MD.

    WP GitHuber MD should, however work on my GoDaddy Business WordPress website.

    The plugin is designed to work with any self-hosted WordPress website, regardless of the hosting provider. As long as GoDaddy website meets the minimum requirements for running WordPress and has the ability to install third-party plugins, which it does, then I should be able to use WP GitHuber MD to publish your blog posts from GitHub.

    To install WP GitHuber MD on GoDaddy Business WordPress website, simply follow these steps:

    1. Log in to the WordPress dashboard and navigate to the “Plugins” section.
    2. Click the “Add New” button and search for “WP GitHuber MD”.
    3. Install and activate the plugin.
    4. Follow the plugin’s setup instructions to connect your GitHub account and configure your publishing settings.

    Once the plugin is set up, I can create blog posts in markdown format and push them to your GitHub repository. The plugin will automatically detect the new post and publish it on the Business WordPress website.

    If you have any issues or questions about using WP GitHuber MD, then can contact GoDaddy’s support team for assistance.

    Alternates

    That leave me with maintain productivity with my wordpress.com site.

    Another approach, then, would be to use a third-party service like Zapier or IFTTT to automate the process of publishing blog posts. With these services, I can create a “zap” or “recipe” that triggers when a new markdown file is added to my GitHub repository, and then automatically creates a new post on my WordPress site.

    Here are the general steps to set up a Zapier or IFTTT integration:

    1. Create a new “zap” or “recipe” in Zapier or IFTTT.
    2. Connect to GitHub and WordPress accounts.
    3. Set up the trigger to detect when a new markdown file is added to the GitHub repository.
    4. Set up the action to create a new post on your WordPress site, using the metadata from the markdown file to set the post title, tags, and formatting.
    5. Test the integration to make sure it’s working properly.

    Detail are here

    1. Zapier website: https://zapier.com/
    2. IFTTT website: https://ifttt.com/

    IFTTT

    Here’s a step-by-step guide on how to use IFTTT to publish GitHub commits to WordPress posts:

    1. Sign up for an account on IFTTT (if you haven’t already) at https://ifttt.com/.
    2. Once logged in, click on your username or profile picture at the top-right corner of the page and select “Create” from the dropdown menu.
    3. On the “Create a new Applet” page, click on the “+ This” button.
    4. Search for and select the “GitHub” service.
    5. Choose the trigger event that suits your needs. For example, you can select “New push to repository” if you want a post to be created on WordPress whenever there is a new commit to a specific GitHub repository. Follow the prompts to connect your GitHub account and set up the trigger event.
    6. Click on the “+ That” button.
    7. Search for and select the “WordPress” service.
    8. Choose the action event “Create a post”. Follow the prompts to connect your WordPress account and authorize IFTTT to access it.
    9. Customize the WordPress post settings, such as the title, content, category, and tags. You can use the information from the GitHub commit (like the commit message) by using the available options in IFTTT.
    10. Once you’ve configured the WordPress action, click on the “Create action” button.
    11. Review your applet settings and click on the “Finish” button.

    That’s it! Now, whenever a new commit is made to the specified GitHub repository, IFTTT will automatically create a new post on the WordPress site with the details you specified.

    Remember to test the applet by making a commit to the GitHub repository and checking if the post is created on your WordPress site according to your desired settings.

    Please note that the specific options and steps in IFTTT may vary slightly based on updates and changes to their platform, so make sure to adjust accordingly if there are any differences.

    Zapier

    Here’s a step-by-step guide on how to use Zapier to publish GitHub commits to WordPress posts:

    1. Sign up for an account on Zapier (if you haven’t already) at https://zapier.com/.
    2. Once logged in, click on the “Make a Zap” button at the top-right corner of the page.
    3. On the “Choose App & Event” screen, search and select “GitHub” as the trigger app.
    4. Choose the trigger event that suits your needs. For example, you can select “New Push” if you want a post to be created on WordPress whenever there is a new commit to a specific GitHub repository. Follow the prompts to connect your GitHub account and set up the trigger event.
    5. Once you’ve set up the GitHub trigger, click on the “Continue” button.
    6. On the “Do this…” screen, search and select “WordPress” as the action app.
    7. Choose the action event “Create Post”. Follow the prompts to connect your WordPress account and authorize Zapier to access it.
    8. Customize the WordPress post settings, such as the title, content, category, and tags. You can use the information from the GitHub commit (like the commit message) by using the available options in Zapier.
    9. Once you’ve configured the WordPress action, click on the “Continue” button.
    10. Review your Zap settings and click on the “Test & Continue” button to ensure everything is set up correctly. Zapier will fetch a sample commit from your GitHub repository to test the integration.
    11. If the test is successful, turn on the Zap by clicking on the “Turn on Zap” button.

    Whenever a new commit is made to the specified GitHub repository, Zapier will automatically create a new post on your WordPress site with the details specified.

    Remember to test the Zap by making a commit to the GitHub repository and checking if the post is created on your WordPress site according to your desired settings.

    As always, the instructions are point in time, note that the specific options and steps in Zapier may vary slightly based on updates and changes to their platform, so make sure to adjust accordingly if there are any differences.