From b131495863dd6ab71dddbd75abb97364d7a4ab3f Mon Sep 17 00:00:00 2001 From: Brian Salcedo Date: Thu, 23 Oct 2025 10:01:08 -0400 Subject: [PATCH] feat: initial commit --- README.md | 325 +++++++++++++++++++++++++++++++++++++++++++++++++ action.yaml | 64 ++++++++++ updatecli.yaml | 79 ++++++++++++ 3 files changed, 468 insertions(+) create mode 100644 README.md create mode 100644 action.yaml create mode 100644 updatecli.yaml diff --git a/README.md b/README.md new file mode 100644 index 0000000..59e816a --- /dev/null +++ b/README.md @@ -0,0 +1,325 @@ +# Updatecli Deploy Action + +A Forgejo Action that uses [Updatecli](https://updatecli.io/) to automatically update Helm chart versions and create pull requests for ArgoCD deployments. + +## Overview + +This action automates the process of: + +- Updating the `appVersion` in a Helm chart's `Chart.yaml` with a new application version +- Incrementing the chart's `version` (minor version bump) +- Creating a pull request in a Forgejo repository with the changes + +## Features + +- 🔄 Automatic Helm chart version management +- 📈 Semantic versioning with minor version increments +- 🔀 Automated pull request creation +- 🎯 Support for different target branches (`main`, `master`, `develop`) +- 🏷️ Configurable Docker image tag integration +- 📝 Conventional commit-style PR titles and descriptions +- ⚙️ Custom Updatecli configuration support + +## Usage + +```yaml +name: Update Helm Chart +on: + push: + branches: [main, develop] + +jobs: + update-chart: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Update Helm Chart + uses: your-org/updatecli-deploy@v1 + with: + registry-user: ${{ vars.REGISTRY_USER }} + registry-password: ${{ secrets.REGISTRY_PASSWORD }} + name: my-application + ref-name: ${{ forge.ref_name }} + docker-tag: ${{ forge.sha }} +``` + +## Inputs + +| Input | Description | Required | Default | +| ------------------- | ----------------------------------------------------- | -------- | ----------------------------------------- | +| `updatecli-config` | Path to custom Updatecli configuration file | No | `${{ forge.action_path }}/updatecli.yaml` | +| `registry-url` | Registry URL for the Forgejo instance | No | `git.cleverthis.com` | +| `registry-user` | Username for Forgejo authentication | **Yes** | - | +| `registry-password` | Password/token for Forgejo authentication | **Yes** | - | +| `charts-repo-org` | Organization/owner of the charts repository | No | `infra` | +| `charts-repo-name` | Name of the charts repository | No | `charts` | +| `name` | Name of the Helm chart/application to update | **Yes** | - | +| `ref-name` | Git reference name (branch) that triggered the action | **Yes** | - | +| `docker-tag` | Docker image tag to set as the new app version | **Yes** | - | + +## Environment Variables + +The action uses the following environment variables internally: + +- `REGISTRY_URL`: Constructed from `registry-url` input +- `REGISTRY_USER`: From `registry-user` input +- `REGISTRY_PASSWORD`: From `registry-password` input +- `CHARTS_REPO_ORG`: From `charts-repo-org` input +- `CHARTS_REPO_NAME`: From `charts-repo-name` input +- `TARGET_NAME`: From `name` input +- `NEW_APP_VERSION`: From `docker-tag` input +- `TARGET_BRANCH`: Determined from `ref-name` input + +## Branch Mapping + +The action maps source branches to target branches as follows: + +- `main` or `master` → `master` +- `develop` → `develop` +- Other branches → Action will fail with an error + +## How It Works + +### 1. Version Detection + +- Retrieves the new application version from the `docker-tag` input +- Reads the current chart version from `Chart.yaml` + +### 2. Version Updates + +- Updates the `appVersion` field in `Chart.yaml` with the new application version +- Increments the chart `version` using semantic versioning (minor bump) + +### 3. Pull Request Creation + +- Creates a pull request in the specified Forgejo repository +- Uses conventional commit-style titles: `chore(app-name): bump chart version and set app version to X.X.X` +- Includes a detailed description with change summary + +## Example Scenarios + +### Scenario 1: Main Branch Deployment + +```yaml +- name: Update Production Chart + uses: your-org/updatecli-deploy@v1 + with: + registry-user: ${{ vars.REGISTRY_USER }} + registry-password: ${{ secrets.REGISTRY_PASSWORD }} + name: web-app + ref-name: main + docker-tag: v2.1.0 +``` + +This will: + +- Update `web-app/Chart.yaml` in the `master` branch +- Set `appVersion` to `v2.1.0` +- Increment the chart version (e.g., `1.2.3` → `1.3.0`) + +### Scenario 2: Development Branch + +```yaml +- name: Update Development Chart + uses: your-org/updatecli-deploy@v1 + with: + registry-user: ${{ vars.REGISTRY_USER }} + registry-password: ${{ secrets.REGISTRY_PASSWORD }} + name: api-service + ref-name: develop + docker-tag: ${{ forge.sha }} +``` + +This will target the `develop` branch and use the commit SHA as the app version. + +### Scenario 3: Custom Configuration + +```yaml +- name: Update Chart with Custom Config + uses: your-org/updatecli-deploy@v1 + with: + updatecli-config: .forgejo/workflows/custom-updatecli.yaml + registry-user: ${{ vars.REGISTRY_USER }} + registry-password: ${{ secrets.REGISTRY_PASSWORD }} + name: microservice + ref-name: main + docker-tag: v1.2.3 +``` + +This allows you to use a custom Updatecli configuration file instead of the default one, enabling: + +- Custom version increment strategies (patch, minor, major) +- Different target files or repositories +- Custom pull request templates +- Additional sources and transformations + +## Configuration Files + +### Default updatecli.yaml + +By default, the action uses the built-in `updatecli.yaml` configuration file that defines: + +- **Sources**: Where to get version information +- **Targets**: What files to update and how +- **Actions**: How to create pull requests +- **Transformers**: How to modify versions (semantic version increment) + +### Custom Configuration with `updatecli-config` + +The `updatecli-config` input allows you to override the default configuration with your own custom Updatecli configuration file. This enables advanced customization scenarios: + +#### When to Use Custom Configuration + +- **Different version increment strategies**: Use patch, major, or custom increment logic instead of minor +- **Multiple chart updates**: Update multiple charts or files in a single run +- **Custom PR templates**: Use different pull request titles, descriptions, or labels +- **Additional transformations**: Apply custom version transformations or filters +- **Different target repositories**: Update charts in different repositories +- **Complex workflows**: Implement multi-step update processes + +#### Example Custom Configuration + +Create a custom configuration file (e.g., `.forgejo/workflows/custom-updatecli.yaml`): + +```yaml +name: Custom Helm Chart Updates + +scms: + helm-chart: + kind: gitea + spec: + url: '{{ requiredEnv "REGISTRY_URL" }}' + username: '{{ requiredEnv "REGISTRY_USER" }}' + token: '{{ requiredEnv "REGISTRY_PASSWORD" }}' + owner: '{{ requiredEnv "CHARTS_REPO_ORG" }}' + repository: '{{ requiredEnv "CHARTS_REPO_NAME" }}' + branch: '{{ requiredEnv "TARGET_BRANCH" }}' + +sources: + appVersion: + name: Get new app version from environment + kind: shell + spec: + command: echo "$NEW_APP_VERSION" + environments: + - name: NEW_APP_VERSION + + currentChartVersion: + scmid: helm-chart + name: Get current chart version + kind: yaml + spec: + file: '{{ requiredEnv "TARGET_NAME" }}/Chart.yaml' + key: $.version + +targets: + updateAppVersion: + scmid: helm-chart + name: Update appVersion in Chart.yaml + kind: yaml + sourceid: appVersion + spec: + file: '{{ requiredEnv "TARGET_NAME" }}/Chart.yaml' + key: $.appVersion + + updateChartVersion: + scmid: helm-chart + name: Increment chart version + kind: yaml + sourceid: currentChartVersion + spec: + file: '{{ requiredEnv "TARGET_NAME" }}/Chart.yaml' + key: $.version + transformers: + # Custom: Use patch increment instead of minor + - semverinc: "patch" + +actions: + pullrequest: + kind: gitea/pullrequest + scmid: helm-chart + spec: + url: '{{ requiredEnv "SERVER_URL" }}' + owner: '{{ requiredEnv "REPO_OWNER" }}' + repository: '{{ requiredEnv "REPO_NAME" }}' + username: '{{ requiredEnv "REGISTRY_USER" }}' + token: '{{ requiredEnv "REGISTRY_PASSWORD" }}' + # Custom PR title + title: 'feat({{ requiredEnv "TARGET_NAME" }}): update to {{ source "appVersion" }}' + # Custom PR body + body: | + ## 🚀 Automated Update + + This PR updates the **{{ requiredEnv "TARGET_NAME" }}** chart with the latest version. + + ### Changes + - App version: `{{ source "appVersion" }}` + - Chart version: patch increment + + ### Checklist + - [x] Version updated automatically + - [ ] Manual review required + - [ ] Deploy to staging first + + --- + *Generated by Updatecli with custom configuration* +``` + +#### Environment Variables Available + +When using custom configurations, all the same environment variables are available: + +- `REGISTRY_URL`: Forgejo registry URL +- `REGISTRY_USER`: Authentication username +- `REGISTRY_PASSWORD`: Authentication token +- `CHARTS_REPO_ORG`: Charts repository organization +- `CHARTS_REPO_NAME`: Charts repository name +- `TARGET_NAME`: Chart/application name +- `NEW_APP_VERSION`: New application version +- `TARGET_BRANCH`: Target branch (master/develop) +- `SERVER_URL`: Forgejo server URL (derived from REGISTRY_URL) +- `REPO_OWNER`: Repository owner (same as CHARTS_REPO_ORG) +- `REPO_NAME`: Repository name (same as CHARTS_REPO_NAME) + +### Chart.yaml Structure + +Expected Helm chart structure: + +```yaml +apiVersion: v2 +name: my-app +version: 1.2.3 # Will be incremented +appVersion: v1.0.0 # Will be updated with new version +description: My application Helm chart +``` + +## Security Considerations + +- Store Forgejo credentials in Forgejo Secrets +- Use tokens with minimal required permissions +- Ensure the `registry-password` has access to: + - Read the charts repository + - Create pull requests + - Push to branches + +## Troubleshooting + +### Common Issues + +1. **Authentication Failed** + - Verify `registry-user` and `registry-password` are correct + - Ensure the token has sufficient permissions + +2. **Chart Not Found** + - Check that `name` matches the directory name in the charts repository + - Verify `charts-repo-org` and `charts-repo-name` are correct + +3. **Branch Mapping Error** + - Ensure `ref-name` is one of: `main`, `master`, or `develop` + - Check that the target branch exists in the repository + +4. **Version Format Issues** + - Ensure the current chart version follows semantic versioning + - Verify `Chart.yaml` has valid YAML syntax diff --git a/action.yaml b/action.yaml new file mode 100644 index 0000000..9b359eb --- /dev/null +++ b/action.yaml @@ -0,0 +1,64 @@ +name: Updatecli deploy +description: Use Updatecli to update deployments for ArgoCD + +inputs: + updatecli-config: + description: Override default updatecli config + default: ${{ forge.action_path }}/updatecli.yaml + registry-url: + description: Registry URL + default: git.cleverthis.com + registry-user: + description: Registry user + required: true + registry-password: + description: Registry password + required: true + charts-repo-org: + description: Charts repo organization + default: infra + charts-repo-name: + description: Charts repo name + default: charts + name: + description: Repo name + required: true + ref-name: + description: Git ref name + required: true + docker-tag: + description: Docker image tag + required: true + +runs: + using: composite + + steps: + - name: Install updatecli + uses: https://github.com/updatecli/updatecli-action@v2 + + - name: Update Helm chart + shell: bash + env: + REGISTRY_URL: https://${{ inputs.registry-url }} + REGISTRY_USER: ${{ inputs.registry-user }} + REGISTRY_PASSWORD: ${{ inputs.registry-password }} + CHARTS_REPO_ORG: ${{ inputs.charts-repo-org }} + CHARTS_REPO_NAME: ${{ inputs.charts-repo-name }} + run: | + export TARGET_NAME=${{ inputs.name }} + + export NEW_APP_VERSION=${{ inputs.docker-tag }} + echo "New app version: $NEW_APP_VERSION" + + if [ "${{ inputs.ref-name }}" = "main" ] || [ "${{ inputs.ref-name }}" = "master" ]; then + TARGET_BRANCH=master + elif [ "${{ inputs.ref-name }}" = "develop" ]; then + TARGET_BRANCH=develop + else + echo "Unknown target branch. We are not coming from main, master, nor develop branch." + exit 1 + fi + + export TARGET_BRANCH + updatecly apply --config ${{ inputs.updatecli-config }} diff --git a/updatecli.yaml b/updatecli.yaml new file mode 100644 index 0000000..2fffa0b --- /dev/null +++ b/updatecli.yaml @@ -0,0 +1,79 @@ +name: Update Helm Chart Versions + +scms: + helm-chart: + kind: gitea + spec: + url: '{{ requiredEnv "REGISTRY_URL" }}' + username: '{{ requiredEnv "REGISTRY_USER" }}' + token: '{{ requiredEnv "REGISTRY_PASSWORD" }}' + owner: '{{ requiredEnv "CHARTS_REPO_ORG" }}' + repository: '{{ requiredEnv "CHARTS_REPO_NAME" }}' + branch: '{{ requiredEnv "TARGET_BRANCH" }}' + +sources: + appVersion: + name: Get new app version from environment + kind: shell + spec: + command: echo "$NEW_APP_VERSION" + environments: + - name: NEW_APP_VERSION + + currentChartVersion: + scmid: helm-chart + name: Get current chart version + kind: yaml + spec: + file: '{{ requiredEnv "TARGET_NAME" }}/Chart.yaml' + key: $.version + +targets: + updateAppVersion: + scmid: helm-chart + name: Update appVersion in Chart.yaml + kind: yaml + sourceid: appVersion + spec: + file: '{{ requiredEnv "TARGET_NAME" }}/Chart.yaml' + key: $.appVersion + + updateChartVersion: + scmid: helm-chart + name: Increment chart version + kind: yaml + sourceid: currentChartVersion + spec: + file: '{{ requiredEnv "TARGET_NAME" }}/Chart.yaml' + key: $.version + transformers: + - semverinc: "minor" + +actions: + pullrequest: + kind: gitea/pullrequest + scmid: helm-chart + spec: + url: '{{ requiredEnv "SERVER_URL" }}' + owner: '{{ requiredEnv "REPO_OWNER" }}' + repository: '{{ requiredEnv "REPO_NAME" }}' + username: '{{ requiredEnv "REGISTRY_USER" }}' + token: '{{ requiredEnv "REGISTRY_PASSWORD" }}' + title: 'chore({{ requiredEnv "TARGET_NAME" }}): bump chart version and set app version to {{ source "appVersion" }}' + body: | + ## Summary + + Automated version bump triggered by CI/CD pipeline following conventional commits. + + ## Changes + + - **Chart version**: incremented minor version + - **App version**: updated to {{ source "appVersion" }} + + ## Type of Change + + - [x] Chore (maintenance, dependencies, version bumps) + + --- + + This PR was automatically created by Updatecli.