<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: sujay malghan</title>
    <description>The latest articles on DEV Community by sujay malghan (@sujay_malghan_).</description>
    <link>https://dev.to/sujay_malghan_</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1504999%2F3b7ed4c6-7cd7-4a8f-afde-ae9e2ac4b519.jpg</url>
      <title>DEV Community: sujay malghan</title>
      <link>https://dev.to/sujay_malghan_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sujay_malghan_"/>
    <language>en</language>
    <item>
      <title>RepoGuardian: Auto-Fix GitHub Repos with Pulumi and Python</title>
      <dc:creator>sujay malghan</dc:creator>
      <pubDate>Sun, 30 Mar 2025 10:19:53 +0000</pubDate>
      <link>https://dev.to/sujay_malghan_/repoguardian-auto-fix-github-repos-with-pulumi-and-python-5bi</link>
      <guid>https://dev.to/sujay_malghan_/repoguardian-auto-fix-github-repos-with-pulumi-and-python-5bi</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/pulumi"&gt;Pulumi Deploy and Document Challenge&lt;/a&gt;: Get Creative with Pulumi and GitHub&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built RepoGuardian, a GitHub repository linter and auto-fixer using Pulumi Automation API and the Pulumi GitHub Provider, fully written in Python.&lt;/p&gt;

&lt;p&gt;RepoGuardian scans all repositories under a GitHub account or organization, checks for missing &lt;code&gt;README.md&lt;/code&gt; and &lt;code&gt;LICENSE&lt;/code&gt; files, and automatically commits those files using Pulumi — ensuring consistent documentation across all repositories.&lt;/p&gt;

&lt;p&gt;It runs fully from Python using the Automation API, with no manual Pulumi CLI steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Live Demo Link
&lt;/h2&gt;

&lt;p&gt;This project does not have a web-based demo. It is a backend automation tool meant to be run locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Repo
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/sujaymalghan" rel="noopener noreferrer"&gt;
        sujaymalghan
      &lt;/a&gt; / &lt;a href="https://github.com/sujaymalghan/repo-guardian" rel="noopener noreferrer"&gt;
        repo-guardian
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;RepoGuardian – GitHub Repository Linter and Auto-Fixer&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;RepoGuardian is a Python-based automation tool that audits and fixes common hygiene issues across GitHub repositories. It scans all repositories in a GitHub account or organization, detects missing standard files (like README and LICENSE), and automatically commits them using Pulumi’s GitHub Provider and Automation API.&lt;/p&gt;
&lt;p&gt;This project was built for the "Get Creative with Pulumi + GitHub" Hackathon.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Overview&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;RepoGuardian addresses a common challenge in GitHub repository management: maintaining consistency and proper documentation across multiple repositories.&lt;/p&gt;
&lt;p&gt;It uses Pulumi's infrastructure-as-code approach not for cloud resources, but to programmatically manage and correct GitHub repositories.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Scans all repositories in a GitHub account or organization&lt;/li&gt;
&lt;li&gt;Detects:
&lt;ul&gt;
&lt;li&gt;Missing &lt;code&gt;README.md&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Missing &lt;code&gt;LICENSE&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Automatically fixes the issues by committing files using Pulumi&lt;/li&gt;
&lt;li&gt;Skips empty repositories with no commits&lt;/li&gt;
&lt;li&gt;Fully automated using Pulumi Automation API&lt;/li&gt;
&lt;li&gt;Requires no Pulumi CLI usage&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Technology Stack&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Python 3.x&lt;/li&gt;
&lt;li&gt;Pulumi Automation API&lt;/li&gt;
&lt;li&gt;Pulumi GitHub…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sujaymalghan/repo-guardian" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The repository includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python source code (&lt;code&gt;main.py&lt;/code&gt;, &lt;code&gt;fixer.py&lt;/code&gt;, &lt;code&gt;linter.py&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.env.example&lt;/code&gt; for environment config&lt;/li&gt;
&lt;li&gt;README with detailed usage instructions&lt;/li&gt;
&lt;li&gt;MIT License&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Journey
&lt;/h2&gt;

&lt;p&gt;My goal was to explore how Pulumi could be used beyond infrastructure — to automate GitHub itself.&lt;/p&gt;

&lt;p&gt;I started by writing a linter using PyGitHub to scan for missing &lt;code&gt;README.md&lt;/code&gt; and &lt;code&gt;LICENSE&lt;/code&gt;. Then I integrated Pulumi’s Automation API to dynamically generate a Pulumi program per repository and apply the missing files using the GitHub Provider.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key steps:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Built a repo linter using PyGitHub&lt;/li&gt;
&lt;li&gt;Integrated Pulumi Automation API for programmatic IaC&lt;/li&gt;
&lt;li&gt;Used &lt;code&gt;github.RepositoryFile&lt;/code&gt; to add missing files&lt;/li&gt;
&lt;li&gt;Skipped empty repositories (no commits)&lt;/li&gt;
&lt;li&gt;Handled default branch detection for each repo&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Challenges:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Handling 404 errors from empty repos&lt;/li&gt;
&lt;li&gt;Making sure Pulumi runs without CLI&lt;/li&gt;
&lt;li&gt;Passing environment configs securely&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project taught me how infrastructure-as-code can apply to GitHub workflows — and how powerful Pulumi becomes when combined with API-based automation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Pulumi with GitHub
&lt;/h2&gt;

&lt;p&gt;Pulumi was central to this project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automation API was used to run everything directly from Python&lt;/li&gt;
&lt;li&gt;GitHub Provider managed files like &lt;code&gt;README.md&lt;/code&gt; and &lt;code&gt;LICENSE&lt;/code&gt; inside repos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach meant no Pulumi CLI commands, no YAML files — just Python and clean automation logic.&lt;/p&gt;

&lt;p&gt;I did not use Pulumi Copilot. All logic was implemented manually based on documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation &amp;amp; Usage
&lt;/h2&gt;

&lt;p&gt;Follow these steps to install and run &lt;strong&gt;RepoGuardian&lt;/strong&gt;:&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Clone the Repository
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/sujaymalghan/repo-guardian.git
&lt;span class="nb"&gt;cd &lt;/span&gt;repo-guardian
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. Set Up a Virtual Environment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv
&lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate           &lt;span class="c"&gt;# macOS/Linux&lt;/span&gt;
&lt;span class="c"&gt;# OR&lt;/span&gt;
venv&lt;span class="se"&gt;\S&lt;/span&gt;cripts&lt;span class="se"&gt;\a&lt;/span&gt;ctivate              &lt;span class="c"&gt;# Windows&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. Install Dependencies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  4. Configure Environment Variables
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;.env&lt;/code&gt; file in the root directory with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GITHUB_TOKEN=your_github_token
GITHUB_OWNER=your_github_username_or_org
PULUMI_ACCESS_TOKEN=your_pulumi_token
PULUMI_CONFIG_PASSPHRASE=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: Make sure the GitHub token has access to your repos, and the Pulumi token is valid.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  5. Run the Tool
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scan all repositories under your GitHub account or organization&lt;/li&gt;
&lt;li&gt;Detect missing &lt;code&gt;README.md&lt;/code&gt; or &lt;code&gt;LICENSE&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;Automatically commit those files using Pulumi&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thanks to the Pulumi and DEV teams for hosting this challenge.&lt;br&gt;&lt;br&gt;
This was a great opportunity to explore creative uses of Pulumi and build something meaningful for GitHub workflows.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>pulumichallenge</category>
      <category>github</category>
      <category>api</category>
    </item>
  </channel>
</rss>
