GitHub App Setup
The pipeline can use a GitHub App to update references in your GitOps repository via gitops-image-replacer (for Docker images) or gitops-replacer (for Helm charts). This is required because the pipeline needs write access to a different repository than the one it's running in.
Why a GitHub App?
| Method | Cross-Repo Write | Token Expiry | Granular Permissions |
|---|---|---|---|
GITHUB_TOKEN |
No | Per-job | No |
| Personal Access Token (PAT) | Yes | Manual | No |
| GitHub App | Yes | Auto (1h) | Yes |
GitHub Apps are the recommended approach because:
- Tokens expire automatically (1 hour)
- Fine-grained permissions per repository
- Not tied to a personal account
- Audit log shows app actions separately
Step 1: Create the GitHub App
- Go to GitHub Settings → Developer settings → GitHub Apps → New GitHub App
Or use this direct link: https://github.com/settings/apps/new
- Fill in the basic information:
| Field | Value |
|---|---|
| GitHub App name | gitops-deployer (or your choice) |
| Homepage URL | Your repository URL |
| Webhook | Uncheck "Active" (not needed) |
- Set Repository permissions:
| Permission | Access |
|---|---|
| Contents | Read and write |
This is the only permission needed. The app will commit image reference updates to your GitOps repository.
-
Set Where can this GitHub App be installed?:
-
Select Only on this account (recommended)
-
Click Create GitHub App
Step 2: Note the App ID
After creation, you'll see the App settings page.
- Find the App ID (a number like
123456) - Save this as the
GITOPS_APP_IDsecret in your image repository
Step 3: Generate a Private Key
- Scroll down to Private keys
- Click Generate a private key
- A
.pemfile will be downloaded - Save the entire contents of this file as the
GITOPS_APP_PRIVATE_KEYsecret
The private key looks like this:
Step 4: Install the App
The app must be installed on the GitOps repository to grant access.
- Go to Install App in the left sidebar
- Click Install next to your account/organization
- Select Only select repositories
- Choose your GitOps repository (e.g.,
myorg/gitops) - Click Install
Step 5: Configure Secrets
Add these secrets to your image repository (not the GitOps repo):
| Secret | Value |
|---|---|
GITOPS_APP_ID |
The App ID from Step 2 |
GITOPS_APP_PRIVATE_KEY |
The entire .pem file contents from Step 3 |
Adding secrets via GitHub UI
- Go to your image repository → Settings → Secrets and variables → Actions
- Click New repository secret
- Add
GITOPS_APP_IDwith the App ID - Add
GITOPS_APP_PRIVATE_KEYwith the private key contents
Adding secrets via GitHub CLI
gh secret set GITOPS_APP_ID --body "123456"
gh secret set GITOPS_APP_PRIVATE_KEY < path/to/private-key.pem
Usage with gitops-image-replacer (Docker Images)
After the Docker build completes, use gitops-image-replacer to update image references in your GitOps repository:
jobs:
build:
uses: slauger/container-gitops-pipeline/.github/workflows/docker-build.yaml@v1
with:
image_name: my-app
update-gitops:
needs: build
runs-on: ubuntu-latest
steps:
- name: Generate token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.GITOPS_APP_ID }}
private-key: ${{ secrets.GITOPS_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: gitops
- name: Update GitOps
uses: slauger/gitops-image-replacer@v1
with:
token: ${{ steps.app-token.outputs.token }}
repository: myorg/gitops
file: apps/my-app/values.yaml
image: ${{ needs.build.outputs.image }}
Usage with gitops-replacer (Helm Charts)
After the Helm chart build completes, use gitops-replacer to update chart version references in your GitOps repository.
First, add a marker comment in your target file (e.g., Chart.yaml):
dependencies:
# gitops-replacer: my-chart
- name: my-chart
version: "0.0.0-abc1234"
repository: oci://ghcr.io/myorg
Then configure the workflow:
jobs:
build:
uses: slauger/container-gitops-pipeline/.github/workflows/helm-oci.yaml@v1
with:
chart_path: '.'
update-gitops:
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Generate token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.GITOPS_APP_ID }}
private-key: ${{ secrets.GITOPS_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: gitops
- name: Install gitops-replacer
run: pip install gitops-replacer
- name: Update GitOps
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
gitops-replacer --apply "${{ needs.build.outputs.version }}"
The gitops-replacer.json config in your chart repository:
{
"gitops-replacer": [
{
"repository": "myorg/gitops",
"branch": "main",
"file": "apps/my-app/Chart.yaml",
"depName": "my-chart",
"when": "^refs/heads/main$"
}
]
}
Verification
After setup, the pipeline will:
- Generate a short-lived token using the App credentials
- Use this token to push commits to your GitOps repository
- The token expires after 1 hour automatically
You can verify the setup by checking:
- GitOps repository → Settings → Integrations → GitHub Apps
- Your app should be listed with "Contents: Read and write"
Troubleshooting
"Resource not accessible by integration"
The app is not installed on the GitOps repository. Go to the app settings and install it on the correct repository.
"Bad credentials"
The private key is incorrect or malformed. Make sure you copied the entire .pem file including the -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- lines.
"Integration not found"
The App ID is incorrect. Double-check the App ID in your GitHub App settings.
Multiple GitOps Repositories
If you deploy to multiple GitOps repositories (e.g., different environments in different repos), install the app on all of them:
- Go to your GitHub App → Install App
- Select Only select repositories
- Add all GitOps repositories that the pipeline needs to update
See Also
- Docker Build
- Helm OCI
- Configuration
- gitops-image-replacer - For Docker images
- gitops-replacer - For Helm charts
- GitHub Docs: Creating a GitHub App