In modern Salesforce development, release cycles move faster than most documentation practices. As teams focus on delivering new features, keeping documentation for Salesforce Apex classes current is often postponed or forgotten.
This article presents a practical GitHub Actions–based workflow that uses AI to create professional markdown documentation for your Apex classes. By combining Salesforce CLI, Ollama-powered local LLMs, and GitHub automation, the pipeline turns Apex code into rich, structured documentation with very little manual work.
7 Key Rules: Achieving DORA-Ready Salesforce Documentation
The Documentation Challenge
Salesforce engineering teams typically struggle with documentation for multiple reasons:
- Limited time that is usually reserved for feature delivery
- Inconsistent manual documentation styles across developers
- Ongoing maintenance overhead as Apex classes evolve
- Knowledge silos where important design details are never formally recorded
This automated pipeline is designed to directly address those issues by generating standardized documentation from your source code. It supports essential organizational goals such as:
- Accelerated Development Workflows
Automatically create consistent documentation for new Apex classes directly within CI/CD pipelines, without interrupting developer focus. - Legacy Code Modernization
Systematically document older or poorly documented codebases to improve maintainability and simplify refactoring. - Enhanced Code Reviews
Generate documentation drafts alongside pull requests to help reviewers quickly understand intent, parameters, and side effects. - Effective Knowledge Transfer
Provide structured documentation that helps onboard new team members and supports cross-team knowledge sharing.
Foundational Concepts
Before diving into the pipeline architecture, it’s important to clarify a few key concepts that underpin the design.
CI/CD
Continuous Integration and Continuous Delivery/Deployment (CI/CD) is an automated software delivery approach. It:
- standardizes build and deployment workflows
- reduces manual release risk
- shortens delivery cycles
- helps prevent production issues by enforcing consistent checks
iBirds Services is an open-source platform that allows teams to run, manage, and interact with large language models (LLMs) locally. It simplifies the process of downloading, configuring, and using models such as DeepSeek, Qwen, LLaMA, and Mistral without complex infrastructure work.
Key applications include:
- Privacy-focused AI – All processing remains on your infrastructure, keeping data local and controlled.
- Offline model interaction – No constant internet connection required.
- Development & prototyping – Easily connect LLMs to internal tools and services via API.
- Experimentation with LLMs – Quickly test, compare, and swap different models.
DeepSeek-Coder 6.7B
DeepSeek-Coder 6.7B is an open-source large language model with 6.7 billion parameters, specialized for code generation and understanding.
Key capabilities:
- Performs strongly on code completion, bug fixing, documentation, and code translation.
- Optimized for 87+ programming languages (including Python, JavaScript, Java, Apex, and more).
- Trained on 2 trillion tokens of high-quality code and natural language data.
- Offers a free alternative to tools like GitHub Copilot or commercial OpenAI APIs.
The Pipeline Architecture
The AI-powered Apex documentation pipeline uses a multi-stage architecture. Each stage plays a specific role in the overall automation:
- Environment Initialization & Dependency Setup
- Prepares the GitHub Actions runner
- Installs Salesforce CLI and required Apex plugins
- Ensures all tools are ready for metadata retrieval and processing
- Prepares the GitHub Actions runner
- Local AI Infrastructure Provisioning
- Installs and configures Ollama as an LLM server inside the GitHub Actions runner
- Removes the need for external AI APIs
- Gives teams full control over which models are used and how they are executed
- Installs and configures Ollama as an LLM server inside the GitHub Actions runner
- Secure Salesforce Authentication & Metadata Extraction
- Uses SFDX URL–based authentication to log in to the target Salesforce org
- Retrieves specific Apex class metadata with a package.xml manifest
- Ensures only the needed classes are pulled for documentation
- Uses SFDX URL–based authentication to log in to the target Salesforce org
- Intelligent Documentation Synthesis
- Sends the raw Apex source code to DeepSeek-Coder 6.7B through carefully designed prompts
- Produces structured markdown documentation in a predefined format (overview, methods, parameters, return values, and examples)
- Sends the raw Apex source code to DeepSeek-Coder 6.7B through carefully designed prompts
- Artifact Packaging & Distribution
- Packages the generated markdown into versioned workflow artifacts
- Makes documentation easily accessible to developers, reviewers, and technical writers
- Allows integration with internal documentation portals or wikis
- Packages the generated markdown into versioned workflow artifacts
Prerequisites
Before you implement this pipeline, confirm that the following prerequisites are available:
- Set Up a GitHub Repository
- Sign in to GitHub.
- Create a private repository for your Salesforce project.
- This repository will host both your source code and the workflow.
- Sign in to GitHub.
- Generate Salesforce Authentication URL
With Salesforce CLI installed locally, authenticate to your Salesforce org and generate the auth URL by running:
sf force:auth:web:login –alias <OrgAlias> –instance-url <OrgURL> –set-default
Then follow these steps:
- When the browser window opens, log in to Salesforce.
- After authentication completes, close the tab.
Next, run:
sf org display –target-org <OrgAlias> –verbose
Copy the value shown after SFDX Auth Url and store it securely. You will use this value as a GitHub secret.
Important Security Note
Treat SFDX Auth URLs as highly sensitive secrets. If exposed, they can provide full authenticated access to your Salesforce org with the permissions of the associated user. In many development environments, this often means administrator-level access.
When connecting to orgs containing sensitive data, always use service accounts and apply the principle of least privilege.
You can also refer to your organization’s security guidelines or internal best practices for additional controls.
Store the Authentication URL in GitHub Secrets
- Go to your GitHub repository.
- Navigate to Settings → Secrets and variables → Actions.
- Click New repository secret and add:
| Secret Name | Description |
| ORG_SFDX_URL | SFDX authentication URL for your Salesforce org |
Save the secret.
Configure Workflow Permissions
Make sure that workflows can run and access the needed resources:
- In repository settings, enable “Allow all actions and reusable workflows” under the Actions permissions section.
The Pipeline Implementation
Create the GitHub Actions workflow that will generate your Apex documentation.
- In your repository, create a new file:
/.github/workflows/Generate_Documentation.yml - Paste the following YAML configuration into the file.
- Save and commit your changes.
name: AI-Powered Apex Documentation Generator
on:
workflow_dispatch:
inputs:
ORG_ALIAS:
type: string
description: “Salesforce org alias”
required: true
default: “dev”
CLASS_NAME:
type: string
description: “Name of the Apex class to generate documentation for”
required: true
default: “GitHubActionTrigger”
env:
ORG_ALIAS: ${{ github.event.inputs.ORG_ALIAS }}
CLASS_NAME: ${{ github.event.inputs.CLASS_NAME }}
jobs:
generate_docs:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
– name: 🏗️ Setup Environment
uses: actions/checkout@v4
with:
fetch-depth: 0
– name: ⚙️ Install Dependencies
run: |
# Install Salesforce CLI
npm install –global @salesforce/cli@latest
sf plugins:install @salesforce/plugin-apex@latest
– name: 🦙 Install & Configure Ollama
run: |
# Install Ollama
curl -fsSL https://ollama.com/install.sh | sh
# Create systemd service file
sudo tee /etc/systemd/system/ollama.service <<EOF
[Unit]
Description=Ollama Service
After=network-online.target
[Service]
ExecStart=/usr/local/bin/ollama serve
User=root
Group=root
Restart=always
RestartSec=3
Environment=”OLLAMA_HOST=0.0.0.0″
Environment=”OLLAMA_MODELS=$HOME/.ollama/models”
[Install]
WantedBy=multi-user.target
EOF
# Start and enable the Ollama service
sudo systemctl daemon-reload
sudo systemctl enable –now ollama # Combined enable and start
# Wait for service initialization and check status
sleep 10
if ! systemctl is-active –quiet ollama; then
echo “❌ Failed to start Ollama service”
journalctl -u ollama -b –no-pager | tail -n 20
exit 1
fi
# Pull model with retries
for i in {1..3}; do
if ollama pull deepseek-coder:6.7b; then
break
else
echo “⚠️ Pull attempt $i failed, retrying…”
sleep 10
fi
done
– name: 🩺 Health Check Ollama
run: |
# Verify server responsiveness
if ! curl -s http://localhost:11434 >/dev/null; then
echo “❌ Ollama server not responding, restarting…”
sudo systemctl restart ollama
sleep 15 # Wait for restart
fi
# Final verification
if ! ollama list >/dev/null; then
echo “❌ Ollama still not responding after restart”
exit 1
fi
– name: 🔐 Authenticate to Salesforce Org
env:
SFDX_URL: ${{ secrets.ORG_SFDX_URL }}
run: |
if [ -z “$SFDX_URL” ]; then
echo “❌ Error: SFDX_URL environment variable is empty”
exit 1
fi
echo “$SFDX_URL” | sf org login sfdx-url \
–alias $ORG_ALIAS \
–set-default \
–sfdx-url-stdin
sf org display
– name: 📦 Retrieve Metadata
run: |
# Create full project structure
sf project generate –name “org-metadata” –manifest
cd ./org-metadata
# Create package.xml
mkdir -p manifest
cat <<EOF > manifest/package.xml
<?xml version=”1.0″ encoding=”UTF-8″?>
<Package xmlns=”http://soap.sforce.com/2006/04/metadata”>
<types>
<members>${{ env.CLASS_NAME }}</members>
<name>ApexClass</name>
</types>
<version>59.0</version>
</Package>
EOF
sf project retrieve start –target-org $ORG_ALIAS –manifest manifest/package.xml
– name: 📝 Generate Markdown Docs
run: |
# Create output directory
mkdir -p generated-docs
# Verify class exists
CLASS_FILE=”org-metadata/force-app/main/default/classes/${{ env.CLASS_NAME }}.cls”
if [ ! -f “$CLASS_FILE” ]; then
echo “❌ Error: Class ${{ env.CLASS_NAME }} not found”
exit 1
fi
# Process the specified class
CLASS=${{ env.CLASS_NAME }}
echo “📄 Processing $CLASS.cls”
# Get sanitized content (4000 chars max)
CONTENT=$(head -c 4000 “$CLASS_FILE” | sed ‘/\/\*/,/\*\//d’ | sed ‘s/\/\/.*$//’)
# Generate with retries
for ATTEMPT in {1..3}; do
echo “Attempt $ATTEMPT/3: Generating docs for $CLASS”
PROMPT=”Generate professional markdown documentation for Salesforce Apex class $CLASS. Follow these rules STRICTLY:
– Only show the final documentation content
– Use ONLY Apex code examples (no Java/JavaScript)
– Never include disclaimers or requirements in output
– Maintain this exact format:
# $CLASS
## Overview
[1-2 sentence class purpose]
## Methods
### methodName()
**Description:** [Functionality]
**Parameters:**
– param1 (Type): [Description]
– param2 (Type): [Description]
**Returns:** [Return type description]
**Example:**
\`\`\`apex
// Proper Apex example
[Relevant code]
\`\`\`
## Usage Notes
[Implementation details]
Class content to document:
$CONTENT”
echo “$PROMPT” | ollama run deepseek-coder:6.7b > “generated-docs/${CLASS}.md”
# Verify output
if [ -s “generated-docs/${CLASS}.md” ] && grep -q “AI-Generated” “generated-docs/${CLASS}.md”; then
echo “✅ Successfully generated $CLASS.md”
break
else
echo “⚠️ Attempt $ATTEMPT failed”
sleep 5
fi
done
# Final failure check
if [ ! -s “generated-docs/${CLASS}.md” ]; then
echo “❌ Failed after 3 attempts – creating empty file”
echo “# Failed to generate docs for $CLASS” > “generated-docs/${CLASS}.md”
fi
– name: 📤 Upload Documentation
uses: actions/upload-artifact@v4
with:
name: apex-documentation
path: “generated-docs/${{ env.CLASS_NAME }}.md”
– name: 📊 Generate Summary
run: |
echo “## Documentation Generation Summary” >> $GITHUB_STEP_SUMMARY
echo “Generated markdown for: \`$CLASS_NAME\`” >> $GITHUB_STEP_SUMMARY
echo “- \`$CLASS_NAME\`” >> $GITHUB_STEP_SUMMARY
The Pipeline Execution and Monitoring
Once the workflow file is in place, you can execute and monitor the pipeline directly from GitHub.
Navigate to GitHub Actions
- Open your GitHub repository.
- Click the “Actions” tab at the top.
Trigger the Workflow
- From the left sidebar, locate the workflow named “AI-Powered Apex Documentation Generator” (or whatever name you chose in the YAML).
- Click the “Run workflow” dropdown.
- Provide the necessary input values (e.g., ORG_ALIAS, CLASS_NAME).
- Start the workflow.
Monitor Real-Time Progress
- After triggering, GitHub will redirect you to the specific run instance.
- You can follow each step as it runs and see whether it succeeds or fails.
- Logs for Salesforce authentication, metadata retrieval, Ollama initialization, and documentation generation will all be available.
Review Results
When the workflow finishes:
- Open the completed workflow run from the Actions history.
- Locate the artifacts section.
- Download the generated artifact containing the markdown documentation file for your Apex class.
- Open and review the resulting documentation, then decide how you want to integrate it into your internal documentation systems.
Resulting Markdown Output
Below is an example of what the AI-generated documentation might look like for an Apex class named GitHubActionTrigger.
GitHubActionTrigger: This Apex class includes methods for interacting with the GitHub API to trigger workflows. It can retrieve default GitHub configuration values and initiate a specific workflow on a repository branch using supplied parameters.
Methods
getDefaultGitHubSettings(String githubFlow)
Fetches default GitHub configuration settings for a given workflow type. These settings typically include the GitHub Owner, Repository, Workflow file, and Branch.
- Parameters:
githubFlow (String) – The identifier of the GitHub flow whose configuration you want to retrieve. - Returns:
A Map<String, String> containing keys such as githubOwner, githubRepo, githubWorkflow, and githubBranch.
Example:
Map<String, String> defaultSettings =
GitHubActionTrigger.getDefaultGitHubSettings(‘Deployment’);
System.debug(defaultSettings); // Map with keys ‘githubOwner’, ‘githubRepo’, etc.
triggerWorkflow(String githubOwner, String githubRepo, String githubWorkflow, String githubBranch, String githubPat, String orgAlias)
Triggers a GitHub Actions workflow on a specified branch of a repository using a Personal Access Token (PAT) for authentication.
- Parameters:
- githubOwner (String): The GitHub username or organization name.
- githubRepo (String): The repository name.
- githubWorkflow (String): The workflow file path (e.g., .github/workflows/test.yml).
- githubBranch (String): The branch on which the workflow should run.
- githubPat (String): The GitHub Personal Access Token used for API authentication.
- orgAlias (String): Salesforce org alias passed as input to the GitHub Action workflow.
- githubOwner (String): The GitHub username or organization name.
- Returns:
A String describing success or failure, along with any details returned by the GitHub API (for debugging or logging).
Example:
String result = GitHubActionTrigger.triggerWorkflow(
‘my-org’,
‘my-repo’,
‘.github/workflows/test.yml’,
‘main’,
‘your_pat_here’,
‘alias123’
);
System.debug(result); // Indicates success or failure, with any returned details
Summary
This AI-powered Apex documentation pipeline represents a significant improvement in how Salesforce teams manage and maintain technical documentation. By combining local AI processing (via Ollama and DeepSeek-Coder 6.7B) with strong Salesforce integration and GitHub-based automation, you can:
- reduce manual documentation work
- keep Apex documentation aligned with code changes
- support secure practices using SFDX URLs and GitHub Secrets
- enhance code review, onboarding, and long-term maintainability
For organizations looking to modernize their Apex documentation process, this pipeline delivers a practical, scalable, and secure solution that grows with your Salesforce development teams—exactly the kind of automated foundation iBirds Software Services helps clients implement and optimize.
Top Essential FAQs
1. What does the AI-powered Apex documentation generator actually automate?
It extracts Apex class metadata, processes it through a local LLM (Ollama + DeepSeek), and outputs standardized markdown documentation without manual drafting.
2. Does this workflow require internet-based AI services?
No. All model inference occurs locally on the GitHub Actions runner via Ollama, ensuring complete offline processing and zero dependency on external AI APIs.
3. How is Salesforce authentication handled securely?
Access is granted through SFDX Auth URLs stored exclusively in GitHub Secrets. No token or credential is ever committed to the repository.
4. Can the pipeline document outdated or legacy Apex code?
Yes. It systematically extracts and documents older Apex classes to support modernization, refactoring, and onboarding.
5. How does this assist code reviews?
It generates structured documentation alongside review cycles, enabling reviewers to understand method purpose, parameters, and return behavior without parsing full Apex file logic.
6. What format does the generated documentation follow?
A predefined markdown format with:
- Class Overview
- Method Inventory
- Parameters
- Return Types
- Apex Code Examples
- Usage Notes
7. What happens if documentation generation fails?
The workflow retries automatically. After three failed attempts, it logs failure and generates an output placeholder for review diagnostics.
8. Can this run automatically on each commit or pull request?
Yes. Though manual dispatch is shown, CI triggers can be extended to:
- merge commits
- deployment branches
- nightly documentation cycles
9. How is local AI execution beneficial for regulated environments?
No source code leaves the build environment.
No third-party AI interaction occurs.
This aligns with financial, healthcare, and government compliance controls.
10. Does this replace human documentation entirely?
No—It automates technical class documentation but does not replace architectural justification or business logic explanation. Developers can add contextual notes post-generation.
If you want, I can now also add:
- Best Practices for Documentation Consistency
- Minimal CI/CD YAML triggers only
- One-page compact reference sheet for engineers
Just reply: “Next: Best Practices”
