# Automate Project Management with Rudder CLI and GitHub Actions

<p>This guide explains how to validate and manage your Rudder CLI projects directly via GitHub workflows.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="key-features">Key features</h2><p>By leveraging the <a href="https://github.com/rudderlabs/rudder-cli-action" >Rudder CLI Project Manager Action</a>, you can:</p>
<ul>
<li>Validate your Rudder CLI project files</li>
<li>Perform a dry run of any changes to your project files</li>
<li>Apply the changes to your RudderStack workspace</li>
</ul>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="prerequisites">Prerequisites</h2><ul>
<li>
<p>A GitHub repository containing your Tracking Plan YAML files</p>
</li>
<li>
<p>Generate a <a href="https://www.rudderstack.com/docs/access-management/service-access-tokens/#workspace-sat" >workspace-level Service Access Token</a> in the RudderStack dashboard with the following <a href="https://www.rudderstack.com/docs/access-management/policies-overview/#resource-permissions" >permissions</a> to manage Data Catalog and Tracking Plans:</p>
</li>
</ul>

<table>
  <thead>
      <tr>
          <th>Resource</th>
          <th>Permissions</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Tracking Plans</td>
          <td><strong>Create &amp; Delete</strong>, <strong>Edit</strong></td>
      </tr>
      <tr>
          <td>Data Catalog</td>
          <td><strong>Edit</strong></td>
      </tr>
  </tbody>
</table>
<ul>
<li><strong>If you&rsquo;re on Free or self-hosted plan, or for testing and development only</strong>: Generate a <a href="https://www.rudderstack.com/docs/access-management/personal-access-tokens/" >Personal Access Token</a> with <strong>Read-Write</strong> role</li>
</ul>

<blockquote class="warning">
  <div class="tip-quote">
    
    <div class="tip-text">Any action authenticated by a Personal Access Token will break if the user generating the token is removed from the organization or there is a breaking change to their permissions.</div>
  </div>
</blockquote>
<p><strong>Token permissions for legacy RBAC system</strong></p>
<p>If you are on the <a href="https://www.rudderstack.com/docs/archive/dashboard-guides/user-management/" >legacy Permissions Management (RBAC) system</a>, your workspace-level Service Access Token should have minimum <strong>Admin</strong> permissions.</p>
<p>See <a href="https://www.rudderstack.com/docs/archive/dashboard-guides/service-access-tokens/#generate-service-access-token" >Generate a workspace-level Service Access Token</a> for steps to create the token.</p>

<figure class="image--main "  >
    <a 
         href="/docs/images/access-management/permissions/legacy/admin.webp"
        
        >
        <img src="/docs/images/access-management/permissions/legacy/admin.webp" 
         alt="workspace-level Service Access Token with Admin permission"  
         
         
        decoding="async" loading="lazy" class="img-shortcode"/>
    </a>
    
</figure>

<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="setup">Setup</h2><p>Follow the steps in the below sections in the exact order to set up the GitHub Actions workflow.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="step-1-configure-repository-secrets">Step 1: Configure repository secrets</h3><ol>
<li>In your GitHub repository, go to <strong>Settings</strong> &gt; <strong>Secrets and variables</strong> &gt; <strong>Actions</strong>.</li>
<li>Add a new repository secret as follows:</li>
</ol>
<ul>
<li><strong>Name</strong>: <code>RUDDERSTACK_ACCESS_TOKEN</code> (use this exact name so it matches the workflow below)</li>
<li><strong>Value</strong>: The access token generated in the <a href="#prerequisites" >Prerequisites</a> section</li>
</ul>

<blockquote class="warning">
  <div class="tip-quote">
    
    <div class="tip-text"><p>RudderStack recommends storing this token in GitHub Secrets and referencing it in your workflow using <code>${{ secrets.RUDDERSTACK_ACCESS_TOKEN }}</code>.</p>
<p><strong>Do not expose the token directly in your workflow files</strong>.</p>
</div>
  </div>
</blockquote>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="step-2-create-actions-workflow">Step 2: Create Actions workflow</h3><p>Create the following workflow in your <code>.github/workflows/</code> directory:</p>
<div class="rs-code">
  <div class="rs-code__head">yaml<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-yaml" data-lang="yaml">name: Manage Rudder CLI projects

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Validate Project Files
        uses: rudderlabs/rudder-cli-action@v1.4.0
        env:
          RUDDERSTACK_ACCESS_TOKEN: ${{ secrets.RUDDERSTACK_ACCESS_TOKEN }}
        with:
          location: &#34;&lt;path_to_root_project_folder&gt;/&#34;
          mode: &#34;validate&#34;

  apply:
    runs-on: ubuntu-latest
    needs: validate
    if: github.ref == &#39;refs/heads/main&#39;
    steps:
      - uses: actions/checkout@v4
      - name: Apply Project Files
        uses: rudderlabs/rudder-cli-action@v1.4.0
        env:
          RUDDERSTACK_ACCESS_TOKEN: ${{ secrets.RUDDERSTACK_ACCESS_TOKEN }}
        with:
          location: &#34;&lt;path_to_root_project_folder&gt;/&#34; #Required
          mode: &#34;apply&#34; #Required</code></pre></div>
</div>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text"><p>Note that:</p>
<ul>
<li>The previous Action <code>rudderlabs/rudder-tracking-plan-action@v1.0.0</code> is now deprecated.</li>
<li>You can update the CLI action version by modifying the <code>uses</code> parameter in the workflow file — see the <a href="https://github.com/rudderlabs/rudder-cli-action/releases" >Rudder CLI Project Manager Action releases</a> for the latest version.</li>
</ul></div>
  </div>
</blockquote>

</html>
<p>Some of the key inputs are described below:</p>
<table>
  <thead>
      <tr>
          <th>Input</th>
          <th>Description</th>
          <th>Default value</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>location</code> <br/> Required</td>
          <td>Path to the folder containing the Rudder CLI project files.</td>
          <td>-</td>
      </tr>
      <tr>
          <td><code>mode</code> <br/> Required</td>
          <td>Operation mode — acceptable values are <code>validate</code>, <code>dry-run</code>, and <code>apply</code>. <br /><br />See <a href="#modes" >Modes</a> for more information.</td>
          <td>-</td>
      </tr>
      <tr>
          <td><code>cli_version</code></td>
          <td>Version of the Rudder CLI tool to use.</td>
          <td><code>v0.10.0</code></td>
      </tr>
      <tr>
          <td><code>RUDDERSTACK_ACCESS_TOKEN</code> <br/> Required</td>
          <td>The <a href="#prerequisites" >access token</a> for the RudderStack workspace.</td>
          <td>-</td>
      </tr>
  </tbody>
</table>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="modes">Modes</h4><p>The <code>mode</code> parameter defines the operation mode of the GitHub Action. You can specify either of the following values:</p>
<table>
  <thead>
      <tr>
          <th>Value</th>
          <th>Notes</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>validate</code></td>
          <td><ul><li>Validates Tracking Plan syntax and structure.</li><li>No changes are applied to your configuration.</li></ul></td>
      </tr>
      <tr>
          <td><code>dry-run</code></td>
          <td><ul><li>Simulates the application of changes.</li><li>Shows what would be modified without actually making the changes.</li></ul></td>
      </tr>
      <tr>
          <td><code>apply</code></td>
          <td>Applies the relevant changes to your RudderStack workspace.</td>
      </tr>
  </tbody>
</table>
<p>If you apply destination or account specs that use <code>{{ .VAR }}</code> references, see <a href="https://www.rudderstack.com/docs/dev-tools/rudder-cli/variable-substitution/" >How to Use Variable Substitution in Rudder CLI</a>.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="how-it-works">How it works</h2><p>This section explains the GitHub Actions workflow:</p>
<ul>
<li>The action only triggers when files in your root project directory are modified.</li>
<li>The action automatically syncs the changes with RudderStack when you merge them with the <code>main</code> branch. It uses the <code>apply</code> mode (<code>mode: apply</code>) to push the relevant changes.</li>
</ul>
<br />

