From 9bec238f0e60b7b58584661e20682614d48dc705 Mon Sep 17 00:00:00 2001 From: Anket Satbhai Date: Tue, 24 Mar 2026 18:50:35 +0530 Subject: [PATCH 1/3] feat: add tag validation in release changelog and sepearte smurf workflows for helm and docker --- .github/workflows/docker-smurf.yml | 252 ++++++++++++++++++ .../{docker-smurf-helm.yml => helm-smurf.yml} | 249 +++-------------- .../workflows/release-changelog-internal.yml | 12 +- .github/workflows/release-changelog.yml | 60 ++++- .../{docker-smurf-helm.md => docker-smurf.md} | 24 +- docs/helm-smurf.md | 34 +++ docs/release-changelog.md | 128 +++++++++ 7 files changed, 522 insertions(+), 237 deletions(-) create mode 100644 .github/workflows/docker-smurf.yml rename .github/workflows/{docker-smurf-helm.yml => helm-smurf.yml} (51%) rename docs/{docker-smurf-helm.md => docker-smurf.md} (58%) create mode 100644 docs/helm-smurf.md create mode 100644 docs/release-changelog.md diff --git a/.github/workflows/docker-smurf.yml b/.github/workflows/docker-smurf.yml new file mode 100644 index 00000000..fcda7536 --- /dev/null +++ b/.github/workflows/docker-smurf.yml @@ -0,0 +1,252 @@ +--- +name: πŸ¦Έβ€β™‚οΈ Smurf-Docker +'on': + workflow_call: + inputs: + docker_enable: + description: Set to true to run docker commands + type: string + required: false + aws_auth_method: + description: AWS auth method to use like oidc and keys + type: string + required: false + aws_eks_cluster_name: + description: AWS eks cluster name + type: string + required: false + aws_role: + description: AWS OIDC role for aws authentication. + type: string + default: 'false' + provider: + description: Cloud provider (aws, azure, gcp, digitalocean) + type: string + required: false + default: aws + docker_image_name: + description: Docker image name + type: string + required: false + docker_image_tag: + description: Docker image tag + type: string + default: 'latest' + docker_image_tar: + description: Docker image tar + type: string + required: false + default: image + docker_push: + description: Set true for docker push + type: string + required: false + docker_buildkit_enable: + description: Set true to enable docker buildkit + type: string + required: false + default: 'false' + docker_registry: + description: 'The registry to Push Docker Image (aws, az, gcp, hub)' + type: string + default: aws + docker_registry_url: + description: 'The URL of the container registry (e.g., Docker Hub, ECR, GCR, ACR).' + type: string + dockerfile_path: + description: Docker file directory + type: string + default: Dockerfile + docker_build_args: + description: Docker Build Arguments + type: string + required: false + default: key1=val1 + docker_build_platform: + description: Docker Image Build Platform + type: string + default: linux/amd64 + aws_region: + required: false + type: string + description: AWS Region + default: 'us-east-1' + aws_assume_role: + description: Set to True to run Assume another IAM Role step + required: false + type: string + default: 'false' + aws_assume_role_arn: + type: string + description: AWS assume role + required: false + gcp_project_id: + required: false + type: string + description: 'ID of the default project to use for future API calls and invocations.' + gcp_auth_method: + description: GCP auth method to use like wip and json + type: string + required: false + gcp_docker_push: + description: Set to True to Push Images in GCP + type: string + required: false + default: 'false' + gcp_region: + required: false + type: string + description: GCP Region + default: 'us-central1' + gcp_gke_cluster_name: + description: GCP gke cluster name + type: string + required: false + + secrets: + AWS_ACCESS_KEY_ID: + required: false + description: AWS Access Key ID for direct authentication + AWS_SECRET_ACCESS_KEY: + required: false + description: AWS Secret Access Key for direct authentication + AWS_SESSION_TOKEN: + required: false + description: AWS Session Token for direct authentication + GCP_WIP: + required: false + description: 'WIP Connected with Service Account' + GCP_SERVICE_ACCOUNT: + required: false + description: 'GCP service account' + GOOGLE_CREDENTIALS: + required: false + description: 'GCP service account JSON Key' + GCP_SERVICE_ACCOUNT_KEY: + required: false + description: 'GCP service account JSON Key' + aws_set_parameters: + required: false + description: Overriding the default values using --set flag + +jobs: + docker_build: + if: inputs.docker_enable == 'true' + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + steps: + - name: πŸ“¦ Checkout + uses: actions/checkout@v6 + + # - Setup smurf CLI + - name: Setup Smurf + uses: clouddrove/smurf@v1.0.0 + + - name: 🐳 Docker Image Build + if: inputs.docker_buildkit_enable != 'true' + run: | + smurf sdkr build ${{ inputs.docker_image_name }}:${{ inputs.docker_image_tag }} -f ${{ + inputs.dockerfile_path }} --platform ${{ inputs.docker_build_platform }} + --build-arg ${{ inputs.docker_build_args }} + + - name: 🐳 Docker Image Build with Buildkit + if: inputs.docker_buildkit_enable == 'true' + run: | + smurf sdkr build ${{ inputs.docker_image_name }}:${{ inputs.docker_image_tag }} -f ${{ + inputs.dockerfile_path }} --platform ${{ inputs.docker_build_platform }} + --build-arg ${{ inputs.docker_build_args }} --buildkit + + - name: πŸ’Ύ Save Docker Image as Artifact + run: > + docker save ${{ inputs.docker_image_name }}:${{ inputs.docker_image_tag }} -o ${{ + inputs.docker_image_tar }} + + - name: ⬆️ Upload Docker Image Artifact + uses: actions/upload-artifact@v7 + with: + name: '${{ inputs.docker_image_name }}' + path: '${{ inputs.docker_image_tar }}' + + docker_scan_push: + if: inputs.docker_enable == 'true' && inputs.docker_push == 'true' + runs-on: ubuntu-latest + needs: docker_build + permissions: + id-token: write + contents: read + steps: + - name: πŸ“¦ Checkout + uses: actions/checkout@v6 + + # - Setup smurf CLI + - name: Setup Smurf + uses: clouddrove/smurf@v1.0.0 + + - name: ⬇️ Download Docker Image Artifact + uses: actions/download-artifact@v8 + with: + name: '${{ inputs.docker_image_name }}' + + - name: πŸ“₯ Load Docker Image + run: | + docker load -i ${{ inputs.docker_image_tar }} + + - name: 🟦 Install AWS CLI + if: ${{ inputs.provider == 'aws' }} + uses: aws-actions/configure-aws-credentials@v6 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }} + role-to-assume: ${{ secrets.BUILD_ROLE }} + aws-region: ${{ inputs.aws_region }} + role-duration-seconds: 900 + role-skip-session-tagging: true + + - name: πŸ”„ Assume another IAM Role + if: inputs.aws_assume_role == 'true' + uses: aws-actions/configure-aws-credentials@v6 + with: + role-to-assume: ${{ inputs.aws_assume_role_arn }} + aws-region: ${{ inputs.aws_region }} + + - name: ☁️ Authenticate Google Cloud with WIP and Service Account + if: inputs.gcp_auth_method == 'wip' + uses: google-github-actions/auth@v3 + with: + token_format: access_token + workload_identity_provider: ${{ secrets.GCP_WIP }} + service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }} + access_token_lifetime: 300s + project_id: ${{ inputs.gcp_project_id }} + + - name: ☁️ Authenticate Google Cloud with Service Account JSON Key + if: inputs.gcp_auth_method == 'json' + uses: 'google-github-actions/auth@v3' + with: + credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}' + + - name: πŸ›‘οΈ Docker Image Scan + run: | + smurf sdkr scan ${{ inputs.docker_image_name }}:${{ inputs.docker_image_tag }} + + - name: 🏷️ Docker Image Tag + if: inputs.docker_push == 'true' + run: | + smurf sdkr tag ${{ inputs.docker_image_name }}:${{ inputs.docker_image_tag }} ${{ + inputs.docker_registry_url }}/${{ inputs.docker_image_name }}:${{ inputs.docker_image_tag }} + + - name: πŸš€ Docker Image Push + if: inputs.docker_push == 'true' && inputs.gcp_docker_push != 'true' + run: | + smurf sdkr push ${{ inputs.docker_registry }} ${{ inputs.docker_registry_url }}/${{ inputs.docker_image_name }}:${{ + inputs.docker_image_tag }} + + - name: πŸš€ Docker Image Push on gcp + if: inputs.docker_push == 'true' && inputs.gcp_docker_push == 'true' + run: | + smurf sdkr push ${{ inputs.docker_registry }} ${{ inputs.docker_registry_url }}/${{ inputs.docker_image_name }}:${{ + inputs.docker_image_tag }} --project-id ${{ inputs.gcp_project_id }} +... diff --git a/.github/workflows/docker-smurf-helm.yml b/.github/workflows/helm-smurf.yml similarity index 51% rename from .github/workflows/docker-smurf-helm.yml rename to .github/workflows/helm-smurf.yml index 30105a61..0294b2f5 100644 --- a/.github/workflows/docker-smurf-helm.yml +++ b/.github/workflows/helm-smurf.yml @@ -1,12 +1,8 @@ --- -name: πŸ¦Έβ€β™‚οΈ Smurf-Docker-Helm +name: πŸ¦Έβ€β™‚οΈ Smurf-Helm 'on': workflow_call: inputs: - docker_enable: - description: Set to true to run docker commands - type: string - required: false aws_auth_method: description: AWS auth method to use like oidc and keys type: string @@ -24,48 +20,6 @@ name: πŸ¦Έβ€β™‚οΈ Smurf-Docker-Helm type: string required: false default: aws - docker_image_name: - description: Docker image name - type: string - required: false - docker_image_tag: - description: Docker image tag - type: string - default: 'latest' - docker_image_tar: - description: Docker image tar - type: string - required: false - default: image - docker_push: - description: Set true for docker push - type: string - required: false - docker_buildkit_enable: - description: Set true to enable docker buildkit - type: string - required: false - default: 'false' - docker_registry: - description: 'The registry to Push Docker Image (aws, az, gcp, hub)' - type: string - default: aws - docker_registry_url: - description: 'The URL of the container registry (e.g., Docker Hub, ECR, GCR, ACR).' - type: string - dockerfile_path: - description: Docker file directory - type: string - default: Dockerfile - docker_build_args: - description: Docker Build Arguments - type: string - required: false - default: key1=val1 - docker_build_platform: - description: Docker Image Build Platform - type: string - default: linux/amd64 helm_enable: description: Set to true to run helm commands type: string @@ -191,137 +145,6 @@ name: πŸ¦Έβ€β™‚οΈ Smurf-Docker-Helm description: Overriding the default values using --set flag jobs: - docker_build: - if: inputs.docker_enable == 'true' - runs-on: ubuntu-latest - permissions: - id-token: write - contents: read - steps: - - name: πŸ“¦ Checkout - uses: actions/checkout@v6 - - # - Setup smurf CLI - - name: Setup Smurf - uses: clouddrove/smurf@v1.0.0 - - - name: 🐳 Docker Image Build - if: inputs.docker_buildkit_enable != 'true' - run: | - smurf sdkr build ${{ inputs.docker_image_name }}:${{ inputs.docker_image_tag }} -f ${{ - inputs.dockerfile_path }} --platform ${{ inputs.docker_build_platform }} - --build-arg ${{ inputs.docker_build_args }} - - - name: 🐳 Docker Image Build with Buildkit - if: inputs.docker_buildkit_enable == 'true' - uses: clouddrove/smurf@v1.0.0 - run: | - smurf sdkr build ${{ inputs.docker_image_name }}:${{ inputs.docker_image_tag }} -f ${{ - inputs.dockerfile_path }} --platform ${{ inputs.docker_build_platform }} - --build-arg ${{ inputs.docker_build_args }} --buildkit - - - name: πŸ’Ύ Save Docker Image as Artifact - run: > - docker save ${{ inputs.docker_image_name }}:${{ inputs.docker_image_tag }} -o ${{ - inputs.docker_image_tar }} - - - name: ⬆️ Upload Docker Image Artifact - uses: actions/upload-artifact@v7 - with: - name: '${{ inputs.docker_image_name }}' - path: '${{ inputs.docker_image_tar }}' - - docker_scan_push: - if: inputs.docker_enable == 'true' && inputs.docker_push == 'true' - runs-on: ubuntu-latest - needs: docker_build - permissions: - id-token: write - contents: read - steps: - - name: πŸ“¦ Checkout - uses: actions/checkout@v6 - - - name: ⬇️ Download Docker Image Artifact - uses: actions/download-artifact@v8 - with: - name: '${{ inputs.docker_image_name }}' - - - name: πŸ“₯ Load Docker Image - run: | - docker load -i ${{ inputs.docker_image_tar }} - - - name: πŸ”‘ Configure AWS credentials with OIDC - if: inputs.aws_auth_method == 'oidc' - uses: aws-actions/configure-aws-credentials@v6 - with: - role-to-assume: ${{ inputs.aws_role }} - aws-region: ${{ inputs.aws_region }} - - - name: πŸ”„ Assume another IAM Role - if: inputs.aws_assume_role == 'true' - uses: aws-actions/configure-aws-credentials@v6 - with: - role-to-assume: ${{ inputs.aws_assume_role_arn }} - aws-region: ${{ inputs.aws_region }} - - - name: πŸ”‘ Configure AWS credentials with access keys - if: inputs.aws_auth_method == 'keys' - env: - AWS_ACCESS_KEY_ID: '${{ secrets.AWS_ACCESS_KEY_ID }}' - AWS_SECRET_ACCESS_KEY: '${{ secrets.AWS_SECRET_ACCESS_KEY }}' - AWS_SESSION_TOKEN: '${{ secrets.AWS_SESSION_TOKEN }}' - aws-region: ${{ inputs.aws_region }} - run: | - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY - if [[ -n "$AWS_SESSION_TOKEN" ]]; then - aws configure set aws_session_token $AWS_SESSION_TOKEN - fi - aws configure set region $AWS_REGION - - - name: ☁️ Authenticate Google Cloud with WIP and Service Account - if: inputs.gcp_auth_method == 'wip' - uses: google-github-actions/auth@v3 - with: - token_format: access_token - workload_identity_provider: ${{ secrets.GCP_WIP }} - service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }} - access_token_lifetime: 300s - project_id: ${{ inputs.gcp_project_id }} - - - name: ☁️ Authenticate Google Cloud with Service Account JSON Key - if: inputs.gcp_auth_method == 'json' - uses: 'google-github-actions/auth@v3' - with: - credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}' - - - name: πŸ›‘οΈ Docker Image Scan - uses: clouddrove/smurf@v1.0.0 - run: | - smurf sdkr scan ${{ inputs.docker_image_name }}:${{ inputs.docker_image_tag }} - - - name: 🏷️ Docker Image Tag - if: inputs.docker_push == 'true' - uses: clouddrove/smurf@v1.0.0 - run: | - smurf sdkr tag ${{ inputs.docker_image_name }}:${{ inputs.docker_image_tag }} ${{ - inputs.docker_registry_url }}/${{ inputs.docker_image_name }}:${{ inputs.docker_image_tag }} - - - name: πŸš€ Docker Image Push - if: inputs.docker_push == 'true' && inputs.gcp_docker_push != 'true' - uses: clouddrove/smurf@v1.0.0 - run: | - push ${{ inputs.docker_registry }} ${{ inputs.docker_registry_url }}/${{ inputs.docker_image_name }}:${{ - inputs.docker_image_tag }} - - - name: πŸš€ Docker Image Push in GCP - if: inputs.docker_push == 'true' && inputs.gcp_docker_push == 'true' - uses: clouddrove/smurf@v1.0.0 - run: | - push ${{ inputs.docker_registry }} ${{ inputs.docker_registry_url }}/${{ inputs.docker_image_name }}:${{ - inputs.docker_image_tag }} --project-id ${{ inputs.gcp_project_id }} - helm_lint_template: if: inputs.helm_enable == 'true' runs-on: ubuntu-latest @@ -351,12 +174,21 @@ jobs: - name: πŸ“¦ Checkout uses: actions/checkout@v6 - - name: πŸ”‘ Configure AWS credentials with OIDC - if: inputs.aws_auth_method == 'oidc' + # - Setup smurf CLI + - name: Setup Smurf + uses: clouddrove/smurf@v1.0.0 + + - name: 🟦 Install AWS CLI + if: ${{ inputs.provider == 'aws' }} uses: aws-actions/configure-aws-credentials@v6 with: - role-to-assume: '${{ inputs.aws_role }}' + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }} + role-to-assume: ${{ secrets.BUILD_ROLE }} aws-region: ${{ inputs.aws_region }} + role-duration-seconds: 900 + role-skip-session-tagging: true - name: πŸ”„ Assume another IAM Role if: inputs.aws_assume_role_arn == 'true' @@ -365,21 +197,6 @@ jobs: role-to-assume: '${{ inputs.aws_assume_role_arn }}' aws-region: ${{ inputs.aws_region }} - - name: πŸ”‘ Configure AWS credentials with access keys - if: inputs.aws_auth_method == 'keys' - env: - AWS_ACCESS_KEY_ID: '${{ secrets.AWS_ACCESS_KEY_ID }}' - AWS_SECRET_ACCESS_KEY: '${{ secrets.AWS_SECRET_ACCESS_KEY }}' - AWS_SESSION_TOKEN: '${{ secrets.AWS_SESSION_TOKEN }}' - AWS_REGION: ${{ inputs.aws_region }} - run: | - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY - if [[ -n "$AWS_SESSION_TOKEN" ]]; then - aws configure set aws_session_token $AWS_SESSION_TOKEN - fi - aws configure set region $AWS_REGION - - name: 🌎 Set environment variables run: | echo "AWS_DEFAULT_REGION=${{ inputs.aws_region }}" >> $GITHUB_ENV @@ -393,6 +210,10 @@ jobs: echo "GOOGLE_APPLICATION_CREDENTIALS=/tmp/gcp-key.json" >> $GITHUB_ENV shell: bash + - name: Update Kubernetes KubeConfig + run : | + aws eks update-kubeconfig --name ${{ inputs.aws_eks_cluster_name }} --region ${{ inputs.aws_region }} + - name: πŸ”Œ Helm Plugin if: inputs.helm_plugin_install == 'true' run: | @@ -425,34 +246,28 @@ jobs: - name: πŸ“¦ Checkout Repository uses: actions/checkout@v6 - - name: πŸ”‘ Configure AWS credentials with OIDC - if: inputs.aws_auth_method == 'oidc' + # - Setup smurf CLI + - name: Setup Smurf + uses: clouddrove/smurf@v1.0.0 + + - name: 🟦 Install AWS CLI + if: ${{ inputs.provider == 'aws' }} uses: aws-actions/configure-aws-credentials@v6 with: - role-to-assume: ${{ inputs.aws_role }} + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }} + role-to-assume: ${{ secrets.BUILD_ROLE }} aws-region: ${{ inputs.aws_region }} + role-duration-seconds: 900 + role-skip-session-tagging: true - name: πŸ”„ Assume another IAM Role if: inputs.aws_assume_role_arn == 'true' uses: aws-actions/configure-aws-credentials@v6 with: - role-to-assume: '${{ inputs.aws_role }}' - aws-region: ${{ inputs.aws_region }} - - - name: πŸ”‘ Configure AWS credentials with access keys - if: inputs.aws_auth_method == 'keys' - env: - AWS_ACCESS_KEY_ID: '${{ secrets.AWS_ACCESS_KEY_ID }}' - AWS_SECRET_ACCESS_KEY: '${{ secrets.AWS_SECRET_ACCESS_KEY }}' - AWS_SESSION_TOKEN: '${{ secrets.AWS_SESSION_TOKEN }}' + role-to-assume: '${{ inputs.aws_assume_role_arn }}' aws-region: ${{ inputs.aws_region }} - run: | - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY - if [[ -n "$AWS_SESSION_TOKEN" ]]; then - aws configure set aws_session_token $AWS_SESSION_TOKEN - fi - aws configure set region $AWS_REGION - name: 🌎 Set environment variables run: | @@ -466,6 +281,10 @@ jobs: echo "GOOGLE_APPLICATION_CREDENTIALS=/tmp/gcp-key.json" >> $GITHUB_ENV shell: bash + - name: Update Kubernetes KubeConfig + run : | + aws eks update-kubeconfig --name ${{ inputs.aws_eks_cluster_name }} --region ${{ inputs.aws_region }} + - name: βͺ Helm Rollback run: | smurf selm rollback ${{ inputs.helm_release_name }} ${{ inputs.helm_revision }} -n=${{ diff --git a/.github/workflows/release-changelog-internal.yml b/.github/workflows/release-changelog-internal.yml index f5594ce4..5d96ef4c 100644 --- a/.github/workflows/release-changelog-internal.yml +++ b/.github/workflows/release-changelog-internal.yml @@ -6,17 +6,13 @@ on: tags: - '*' workflow_dispatch: - inputs: - tag: - required: true - type: string - description: "Enter the semantic version tag (eg: 2.3.2) for which you want to update the changelog" jobs: changelog: uses: ./.github/workflows/release-changelog.yml with: - branch: master - tag: ${{ inputs.tag || '' }} + branch: 'master' + tag_format: X.Y.Z + release_tag: ${{ github.ref_name }} secrets: - GITHUB: ${{ secrets.GITHUB }} + GITHUB: ${{ secrets.GITHUB }} ... diff --git a/.github/workflows/release-changelog.yml b/.github/workflows/release-changelog.yml index d481474a..553ae700 100644 --- a/.github/workflows/release-changelog.yml +++ b/.github/workflows/release-changelog.yml @@ -7,17 +7,71 @@ on: branch: required: true type: string - tag: - required: false + tag_format: + required: true + type: string + description: "Repository tag format (e.g., vX.Y.Z or X.Y.Z) - defines how tags should look" + release_tag: + required: true type: string - default: '' + description: "Actual release tag to validate" + + outputs: + valid: + description: "Is release tag valid for this repository" + value: ${{ jobs.tag-validation.outputs.valid }} + secrets: GITHUB: required: true description: 'PAT of the user to run the jobs.' jobs: + tag-validation: + runs-on: ubuntu-latest + outputs: + valid: ${{ steps.check.outputs.valid }} + final_tag: ${{ steps.check.outputs.final_tag }} + + steps: + - name: Validate release tag matches repository format + id: check + run: | + REPO_TAG_FORMAT="${{ inputs.tag_format }}" + RELEASE_TAG="${{ inputs.release_tag }}" + + echo "πŸ“‹ Repository tag format: $REPO_TAG_FORMAT" + echo "🏷️ Release tag: $RELEASE_TAG" + echo "================" + + # Check if repository uses v-prefixed tags + if [[ "$REPO_TAG_FORMAT" == v* ]]; then + # Repository uses v-prefixed format (vX.Y.Z) + if [[ "$RELEASE_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "valid=true" >> $GITHUB_OUTPUT + echo "final_tag=$RELEASE_TAG" >> $GITHUB_OUTPUT + echo "βœ… Release tag matches repository format (v-prefixed)" + else + echo "valid=false" >> $GITHUB_OUTPUT + echo "❌ Repository uses v-prefixed tags (vX.Y.Z) but release tag is: $RELEASE_TAG" + echo "⏭️ Skipping changelog generation" + fi + else + # Repository uses plain format (X.Y.Z) + if [[ "$RELEASE_TAG" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "valid=true" >> $GITHUB_OUTPUT + echo "final_tag=$RELEASE_TAG" >> $GITHUB_OUTPUT + echo "βœ… Release tag matches repository format (plain)" + else + echo "valid=false" >> $GITHUB_OUTPUT + echo "❌ Repository uses plain tags (X.Y.Z) but release tag is: $RELEASE_TAG" + echo "⏭️ Skipping changelog generation" + fi + fi + create_changelog: + needs: tag-validation + if: needs.tag-validation.outputs.valid == 'true' runs-on: ubuntu-latest steps: diff --git a/docs/docker-smurf-helm.md b/docs/docker-smurf.md similarity index 58% rename from docs/docker-smurf-helm.md rename to docs/docker-smurf.md index d7f85560..3cb6be6a 100644 --- a/docs/docker-smurf-helm.md +++ b/docs/docker-smurf.md @@ -1,31 +1,33 @@ -## [Smurf-Docker-Helm Workflow](https://github.com/clouddrove/github-shared-workflows/blob/master/.github/workflows/docker-smurf-helm.yml) +## [Smurf-Docker-Helm Workflow](https://github.com/clouddrove/github-shared-workflows/blob/master/.github/workflows/docker-smurf.yml) -This workflow is used to work with Docker and Helm using Smurf. It utilizes the workflows defined in `.github/workflows/docker-smurf-helm.yml` +This workflow is used to work with Docker and Helm using Smurf. It utilizes the workflows defined in `.github/workflows/docker-smurf.yml` #### Usage -The following workflow can work with Docker and Helm Using Smurf tool. It can Build Images, Scan and Push. Talking about the Helm part it can Lint, Template, Deploy and also provides Rollback feature. +The following workflow can work with Docker Using Smurf tool. It can Build Images, Scan and Push. + +It handles: +- 🐳 Build Docker image +- πŸ’Ύ Save image as artifact +- πŸ›‘οΈ Scan image for vulnerabilities +- 🏷️ Tag image for registry +- πŸš€ Push image to registry (AWS / GCP / others) + #### Example for Smurf-Docker-Helm ```yaml -name: Smurf-Docker-Helm +name: Smurf-Docker on: push: jobs: dev: - uses: clouddrove/github-shared-workflows/.github/workflows/docker-smurf-helm.yml@v2 + uses: clouddrove/github-shared-workflows/.github/workflows/docker-smurf.yml@v2 with: docker_image_name: # Image Name docker_image_tag: # Image Tag dockerfile_path: # Dockerfile path docker_registry_url: # Registry URL docker_registry: # Registry - helm_release_name: # Release name - helm_chart_directory: # Helm Chart Directory - helm_enable: # Set to True for Helm Work - helm_values_file_path: # Helm Chart Values Path - helm_namespace: # Namespace - timeout: # Timeout secrets: set-parameters: --set image.tag=${{ github.run_id }} diff --git a/docs/helm-smurf.md b/docs/helm-smurf.md new file mode 100644 index 00000000..12f7a509 --- /dev/null +++ b/docs/helm-smurf.md @@ -0,0 +1,34 @@ +## [Smurf-Docker-Helm Workflow](https://github.com/clouddrove/github-shared-workflows/blob/master/.github/workflows/helm-smurf.yml) + +This workflow is used to work with Helm using Smurf. It utilizes the workflows defined in `.github/workflows/helm-smurf.yml` + +#### Usage +The following workflow can work with Helm Using Smurf tool. Talking about the Helm part it can Lint, Template, Deploy and also provides Rollback feature. + +It automates Helm operations for Kubernetes: +- βœ… Helm lint (validate chart) +- βœ… Helm template (render manifests) +- βœ… Helm deploy (install/upgrade release) +- βœ… Helm rollback (revert to previous version) + +#### Example for Smurf-Docker-Helm + +```yaml +name: Smurf-Helm +on: + push: + +jobs: + dev: + uses: clouddrove/github-shared-workflows/.github/workflows/helm-smurf.yml@v2 + with: + helm_release_name: # Release name + helm_chart_directory: # Helm Chart Directory + helm_enable: # Set to True for Helm Work + helm_values_file_path: # Helm Chart Values Path + helm_namespace: # Namespace + timeout: # Timeout + secrets: + set-parameters: + --set password=${{ secrets.PASSWORD }} +``` \ No newline at end of file diff --git a/docs/release-changelog.md b/docs/release-changelog.md new file mode 100644 index 00000000..ec63b9f8 --- /dev/null +++ b/docs/release-changelog.md @@ -0,0 +1,128 @@ +# πŸ“„ CHANGELOG Workflow + +This reusable GitHub Actions workflow automates: + +- βœ… Release tag validation based on repository format +- πŸ“ CHANGELOG.md generation +- πŸš€ GitHub Release creation +- πŸ”„ Automatic commit of updated CHANGELOG + +--- + +## πŸ“¦ Workflow Location + +``` +clouddrove/github-shared-workflows/.github/workflows/release-changelog.yml@v2 +``` + +--- + +## βš™οΈ Inputs + +| Name | Required | Type | Description | +|--------------|----------|--------|-------------| +| `branch` | βœ… Yes | string | Target branch where CHANGELOG.md will be committed | +| `tag_format` | βœ… Yes | string | Repository tag format (`vX.Y.Z` or `X.Y.Z`) | +| `release_tag`| βœ… Yes | string | Actual release tag to validate | + +--- + +## πŸ” Secrets + +| Name | Required | Description | +|----------|----------|-------------| +| `GITHUB` | βœ… Yes | Personal Access Token (PAT) with repo permissions | + +--- + +## πŸ“€ Outputs + +| Name | Description | +|--------|-------------| +| `valid` | Indicates whether the release tag matches the repository format | + +--- + +## 🧠 How It Works + +### 1. Tag Validation + +The workflow checks if the provided `release_tag` matches the repository's `tag_format`. + +#### Supported Formats: + +- `v1.2.3` β†’ Version with `v` prefix +- `1.2.3` β†’ Plain version + +If the tag format does not match: +- ❌ Workflow skips changelog generation +- ❌ No release is created + +--- + +### 2. Changelog Generation + +If validation passes: + +- Generates changelog using commit history +- Updates `CHANGELOG.md` + +--- + +### 3. Release Creation + +- Creates or updates GitHub Release +- Uses generated changelog as release notes +- Marks release as **latest** + +--- + +### 4. Commit Changes + +- Commits updated `CHANGELOG.md` to the specified branch + +--- + +## πŸš€ Usage Example + +```yaml +name: Release + +on: + release: + types: [published] + +jobs: + changelog: + uses: clouddrove/github-shared-workflows/.github/workflows/release-changelog.yml@v2 + with: + branch: master + tag_format: vX.Y.Z + release_tag: ${{ github.ref_name }} + secrets: + GITHUB: ${{ secrets.GITHUB_TOKEN }} +``` + +--- + +## ❌ Invalid Tag Examples + +| Format Expected | Invalid Tag | +|----------------|------------| +| `v1.2.3` | `1.2.3` , `v1.2.3-beta` | +| `1.2.3` | `v1.2.3`, `1.2.3-beta` | +| any | `v1.2` / `1.2` / `latest` | + +--- + +## πŸ’‘ Notes + +- Ensure your repository follows a consistent tagging strategy +- This workflow prevents accidental releases with incorrect tag formats +- Supports both prefixed and non-prefixed semantic versioning + +--- + +## πŸ›  Maintained By + +CloudDrove CI Team \ No newline at end of file From 9e91f4a5a73b5b0bdbbf758caf9445717d45d764 Mon Sep 17 00:00:00 2001 From: Anket Satbhai Date: Tue, 24 Mar 2026 18:52:07 +0530 Subject: [PATCH 2/3] feat: add tag validation in release changelog and sepearte smurf workflows for helm and docker --- .github/workflows/release-changelog.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release-changelog.yml b/.github/workflows/release-changelog.yml index 553ae700..17ed92a5 100644 --- a/.github/workflows/release-changelog.yml +++ b/.github/workflows/release-changelog.yml @@ -88,6 +88,7 @@ jobs: excludeTypes: "" includeInvalidCommits: false tag: ${{ inputs.tag != '' && inputs.tag || github.ref_name }} + - name: πŸš€ Create Release uses: ncipollo/release-action@v1.16.0 with: From 3ac9c8c30369cc8da29de48a436045b2fe0b05bd Mon Sep 17 00:00:00 2001 From: Anket Satbhai Date: Tue, 24 Mar 2026 19:08:41 +0530 Subject: [PATCH 3/3] fix: add release changelog docs in REDME.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dad31299..aa7b7f1b 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,7 @@ Above example is just a simple example to call workflow from github shared workf * [Example for scan and push docker image on Dockerhub](./docs/docker-build-push.md#example-for-scan-and-push-docker-image-on-dockerhub) * [Example for scan and push docker image on ECR](./docs/docker-build-push.md#example-for-scan-and-push-docker-image-on-ecr) - [Docker Scout Workflow](./docs/docker-scout.md) -- [Docker Smurf Helm Workflow](./docs/docker-smurf-helm.md) +- [Docker Smurf Helm Workflow](./docs/docker-smurf.md) ### GCP Workflows - [GCP Prowler Workflow](./docs/gcp-prowler.md) @@ -370,4 +370,4 @@ At [CloudDrove][website], has extensive experience in designing, building & migr [linkedin]: https://cpco.io/linkedin [twitter]: https://twitter.com/clouddrove/ [email]: https://clouddrove.com/contact-us.html - [terraform_modules]: https://github.com/clouddrove?utf8=%E2%9C%93&q=terraform-&type=&language= + [terraform_modules]: https://github.com/clouddrove?utf8=%E2%9C%93&q=terraform-&type=&language= \ No newline at end of file