diff --git a/.github/actions/create-github-release-action/README.md b/.github/actions/create-github-release-action/README.md new file mode 100644 index 0000000..117acd5 --- /dev/null +++ b/.github/actions/create-github-release-action/README.md @@ -0,0 +1,37 @@ + + +# ⬆️ Create Github Release Action + +This action creates a new release in the calling repo using the provided version. + +## Usage Example + +```yaml +steps: + - name: Create Github release + uses: onos-project/.github/.github/actions/create-github-release-action@main + with: + version: ${{ steps.version-change.outputs.version }} + env: + GH_TOKEN: ${{ secrets.GH_ONOS_PAT }} +``` + +## Inputs + +| Variable Name | Required | Description | +| ------------- | -------- | ------------ | +| VERSION | True | Version to release on Github | + +## Outputs + +| Variable Name | Description | +| ------------- | ------------- | +| None | | + +## Notes + +This uses the built-in `gh` CLI. A GH_TOKEN with proper permissions should be +included in the env. diff --git a/.github/actions/create-github-release-action/action.yml b/.github/actions/create-github-release-action/action.yml new file mode 100644 index 0000000..907c452 --- /dev/null +++ b/.github/actions/create-github-release-action/action.yml @@ -0,0 +1,25 @@ +--- +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: 2025 The Linux Foundation + +name: "Create Github release" + +inputs: + VERSION: + description: "Version to release on Github" + type: string + required: true + +runs: + using: "composite" + steps: + - name: "Create Github release" + shell: bash + run: | + if gh release create "${{ inputs.VERSION }}" --generate-notes; then + echo "Release ${{ inputs.VERSION }} created ✅" >> "$GITHUB_STEP_SUMMARY" + echo "Release ${{ inputs.VERSION }} created ✅" + else + echo "Failed to create release ${{ inputs.VERSION }} ❌" >> "$GITHUB_STEP_SUMMARY" + echo "Failed to create release ${{ inputs.VERSION }} ❌" + fi diff --git a/.github/actions/find-all-charts-action/action.yml b/.github/actions/find-all-charts-action/action.yml new file mode 100644 index 0000000..e396ad2 --- /dev/null +++ b/.github/actions/find-all-charts-action/action.yml @@ -0,0 +1,32 @@ +--- +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: 2025 The Linux Foundation + +name: "Find all Helm charts" + +inputs: + COMPARISON_BRANCH: + description: "Branch to compare current code with" + required: false + default: "master" + +outputs: + CHARTS: + description: "List of charts that have changed from master" + value: ${{ steps.find_charts.outputs.charts }} + CHARTS_JSON: + description: "Json-formatted list of charts that have changed from master" + value: ${{ steps.find_charts.outputs.charts_json }} + +runs: + using: "composite" + steps: + - name: "Find all helm charts in repo" + id: find_charts + shell: bash + run: | + export COMPARISON_BRANCH=${{ inputs.COMPARISON_BRANCH }} + echo "charts_json=$(${{ github.action_path }}/version_check.sh get_changed_charts | jq -R | jq -sc)" >> $GITHUB_OUTPUT + echo 'charts<> $GITHUB_OUTPUT + ${{ github.action_path }}/version_check.sh get_changed_charts + echo 'EOF' >> $GITHUB_OUTPUT diff --git a/workflows/version_check.sh b/.github/actions/find-all-charts-action/version_check.sh old mode 100644 new mode 100755 similarity index 97% rename from workflows/version_check.sh rename to .github/actions/find-all-charts-action/version_check.sh index ccb6f4d..b2b4dbd --- a/workflows/version_check.sh +++ b/.github/actions/find-all-charts-action/version_check.sh @@ -1,6 +1,7 @@ #!/bin/bash # SPDX-License-Identifier: Apache-2.0 # Copyright 2024 Intel Corporation +# Copyright 2024 The Linux Foundation INPUT=$1 @@ -65,7 +66,7 @@ function is_unique_version() { } case $INPUT in - all) + check_unique) is_unique_version ;; @@ -78,4 +79,3 @@ case $INPUT in exit 2 ;; esac - diff --git a/.github/actions/get-chart-version-action/action.yml b/.github/actions/get-chart-version-action/action.yml new file mode 100644 index 0000000..b7cd4b7 --- /dev/null +++ b/.github/actions/get-chart-version-action/action.yml @@ -0,0 +1,26 @@ +--- +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: 2025 The Linux Foundation + +name: "Get chart version" + +inputs: + CHART_PATH: + description: "Path to chart to check" + required: true + +outputs: + VERSION: + description: "Version of given chart" + value: ${{ steps.get_version.outputs.version }} + +runs: + using: "composite" + steps: + - name: Setup yq + uses: vegardit/gha-setup-yq@v1 + - name: "Get version of chart" + id: get_version + shell: bash + # yamllint disable-line rule:line-length + run: echo "version=$(yq e '.version' ${{ inputs.CHART_PATH }})" >> $GITHUB_OUTPUT diff --git a/workflows/build.yml b/.github/workflows/build.yml similarity index 100% rename from workflows/build.yml rename to .github/workflows/build.yml diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml new file mode 100644 index 0000000..a62d128 --- /dev/null +++ b/.github/workflows/bump-version.yml @@ -0,0 +1,42 @@ +# Copyright 2025 The Linux Foundation +# SPDX-FileCopyrightText: 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 +name: Bump Version +# Calling workflow should include "secrets: inherit" + +on: + workflow_call: + inputs: + version: + required: true + type: string + +jobs: + bump-version: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: increment version + run: | + IFS='.' read -r major minor patch <<< ${{ inputs.version }} + patch_update=$((patch+1)) + NEW_VERSION="$major.$minor.$patch_update-dev" + echo $NEW_VERSION > VERSION + echo "Updated version: $NEW_VERSION" + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v7 + with: + token: ${{ secrets.GH_ONOS_PAT }} + commit-message: Update version + committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + signoff: true + branch: version-update + delete-branch: true + title: Update version + body: | + Update VERSION file + add-paths: | + VERSION diff --git a/workflows/coverage.yml b/.github/workflows/coverage.yml similarity index 100% rename from workflows/coverage.yml rename to .github/workflows/coverage.yml diff --git a/.github/workflows/fossa-scan.yml b/.github/workflows/fossa-scan.yml new file mode 100644 index 0000000..aefd54a --- /dev/null +++ b/.github/workflows/fossa-scan.yml @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2025 Canonical Ltd. +name: Fossa Scan + +on: + workflow_call: + inputs: + branch_name: + description: "Name of the branch to checkout" + required: false + type: string + default: ${{ github.ref }} + +jobs: + fossa-scan: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.branch_name }} + + - name: FOSSA scan + uses: fossa-contrib/fossa-action@v3 + with: + fossa-api-key: 6d304c09a3ec097ba4517724e4a4d17d diff --git a/.github/workflows/helm-lint.yml b/.github/workflows/helm-lint.yml new file mode 100644 index 0000000..5bd3edf --- /dev/null +++ b/.github/workflows/helm-lint.yml @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2025 Canonical Ltd. +name: Lint Helm Charts + +on: + workflow_call: + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Helm + uses: azure/setup-helm@v4 + with: + version: latest + + - name: Find all Charts and Lint them + run: | + for dir in $(find . -maxdepth 1 -mindepth 1 -type d); do + if [[ -f "$dir/Chart.yaml" ]]; then + helm lint "$dir" + fi + done diff --git a/.github/workflows/helm-publish-umbrella.yml b/.github/workflows/helm-publish-umbrella.yml new file mode 100644 index 0000000..3d64bed --- /dev/null +++ b/.github/workflows/helm-publish-umbrella.yml @@ -0,0 +1,103 @@ +# Copyright 2025 Canonical Ltd. +# Copyright 2025 The Linux Foundation +# SPDX-FileCopyrightText: 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 +name: Publish Helm Charts with Umbrella Chart +# Calling workflow should include "secrets: inherit" + +on: + workflow_call: + inputs: + charts_repo_url: + description: "URL for the helm repository to push to" + required: false + type: string + default: https://charts.aetherproject.org + umbrella_charts: + description: "Directory containing the umbrella chart(s)" + required: true + type: string + remote_host: + description: "Address for host to sync charts to" + required: true + type: string + remote_path: + description: "Path on remote_host where charts should be stored" + required: true + type: string + +jobs: + publish: + runs-on: ubuntu-latest + env: + CHARTS_DIR: charts + REF_CHARTS_DIR: charts-ref + steps: + - uses: actions/checkout@v4 + + - name: Set up Helm + uses: azure/setup-helm@v4 + with: + version: latest + + - name: Get current Index.yaml + run: | + rm -rf ${{ env.REF_CHARTS_DIR }} && mkdir -p ${{ env.REF_CHARTS_DIR }} + curl -o ${{ env.REF_CHARTS_DIR }}/index.yaml ${{ inputs.charts_repo_url }}/index.yaml + + - name: Find all Charts and Package them + run: | + rm -rf ${{ env.CHARTS_DIR }} && mkdir -p ${{ env.CHARTS_DIR }} + for dir in $(find . -maxdepth 1 -mindepth 1 -type d); do + if [[ -f "$dir/Chart.yaml" ]] && [[ "$dir" != ${{ inputs.umbrella_charts }} ]]; then + echo "Packaging charts for: $dir" + helm dependency update "$dir" + helm package "$dir" --destination ${{ env.CHARTS_DIR }} + fi + done + helm repo index ${{ env.CHARTS_DIR }} --url ${{ inputs.charts_repo_url }} --merge ${{ env.REF_CHARTS_DIR }}/index.yaml + + - name: Remove not "updated" local Charts (version has not changed) + working-directory: ${{ env.CHARTS_DIR }} + run: | + for file in *.tgz; do + if grep -q "${{ inputs.charts_repo_url }}/$file" "../${{ env.REF_CHARTS_DIR }}/index.yaml"; then + echo "Not publishing $file because it is already in ${{ inputs.charts_repo_url }}/index.yaml" + rm $file + fi + done + + - name: rsync deployments + uses: burnett01/rsync-deployments@7.0.1 + with: + switches: -avh + path: ${{ env.CHARTS_DIR }}/ + remote_path: ${{ inputs.remote_path }} + remote_host: ${{ inputs.remote_host }} + remote_user: ${{ secrets.JENKINS_USERNAME }} + remote_key: ${{ secrets.JENKINS_SSHKEY }} + remote_key_pass: ${{ secrets.JENKINS_PASSPHRASE }} + + - name: Get current Index.yaml + run: | + rm -rf ${{ env.REF_CHARTS_DIR }} && mkdir -p ${{ env.REF_CHARTS_DIR }} + curl -o ${{ env.REF_CHARTS_DIR }}/index.yaml ${{ inputs.charts_repo_url }}/index.yaml + + - name: Find all Charts and Package them + run: | + rm -rf ${{ env.CHARTS_DIR }} && mkdir -p ${{ env.CHARTS_DIR }} + echo "Packaging charts for: ${{ inputs.umbrella_charts }}" + helm dependency update "${{ inputs.umbrella_charts }}" + helm package "${{ inputs.umbrella_charts }}" --destination ${{ env.CHARTS_DIR }} + helm repo index ${{ env.CHARTS_DIR }} --url ${{ inputs.charts_repo_url }} --merge ${{ env.REF_CHARTS_DIR }}/index.yaml + + - name: rsync deployments + uses: burnett01/rsync-deployments@7.0.1 + with: + switches: -avh + path: ${{ env.CHARTS_DIR }}/ + remote_path: ${{ inputs.remote_path }} + remote_host: ${{ inputs.remote_host }} + remote_user: ${{ secrets.JENKINS_USERNAME }} + remote_key: ${{ secrets.JENKINS_SSHKEY }} + remote_key_pass: ${{ secrets.JENKINS_PASSPHRASE }} diff --git a/.github/workflows/license-check.yml b/.github/workflows/license-check.yml new file mode 100644 index 0000000..49556fa --- /dev/null +++ b/.github/workflows/license-check.yml @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2025 Canonical Ltd. +name: License Check + +on: + workflow_call: + inputs: + branch_name: + description: "Name of the branch to checkout" + required: false + type: string + default: ${{ github.ref }} + +jobs: + license-check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.branch_name }} + + - name: reuse lint + uses: fsfe/reuse-action@v5 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..52febf1 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,20 @@ +# SPDX-FileCopyrightText: 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 +on: + pull_request: + branches: + - master + push: + branches: + - master + +jobs: + license-check: + uses: ./.github/workflows/license-check.yml + with: + branch_name: ${{ github.ref }} + + fossa-scan: + uses: ./.github/workflows/fossa-scan.yml + with: + branch_name: ${{ github.ref }} diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml new file mode 100644 index 0000000..bba5155 --- /dev/null +++ b/.github/workflows/push.yml @@ -0,0 +1,182 @@ +--- +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2024 Intel Corporation +# Copyright 2024 The Linux Foundation + +name: Tag/Publish Release + +# yamllint disable-line rule:truthy +on: + push: + branches: + - main + - master + +jobs: + # CAUTION: Other actions depend on this name "tag-github" + tag-github: + runs-on: ubuntu-latest + outputs: + changed: ${{ steps.version-change.outputs.changed }} + version: ${{ steps.version-change.outputs.version }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get changes + id: version-file + # yamllint disable rule:line-length + run: | + if git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | grep VERSION; then + echo "changed=true" >> $GITHUB_OUTPUT + else + echo "VERSION file was not changed" + fi + # yamllint enable rule:line-length + + - name: Validate change in version file + id: version-change + if: steps.version-file.outputs.changed == 'true' + run: | + version=$(cat VERSION) + echo "version=$version" + validate="^[0-9]+\.[0-9]+\.[0-9]+$" + if [[ $version =~ $validate ]]; then + echo "changed=true" >> $GITHUB_OUTPUT + echo "version=$version" >> $GITHUB_OUTPUT + else + echo "Version change not for release" + fi + + - name: Create release using REST API + if: steps.version-change.outputs.changed == 'true' + # yamllint disable rule:line-length + run: | + curl -L \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GH_OMEC_PAT }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${{ github.repository }}/releases \ + -d '{ + "tag_name": "${{ steps.version-change.outputs.version }}", + "target_commitish": "${{ github.event.repository.default_branch }}", + "name": "${{ steps.version-change.outputs.version }}", + "draft": false, + "prerelease": false, + "generate_release_notes": true + }' + # yamllint enable rule:line-length + + publish: + runs-on: ubuntu-latest + needs: tag-github + if: github.repository_owner == 'onosproject' + env: + CHARTS_REPO_URL: https://charts.aetherproject.org + CHARTS_DIR: charts + REF_CHARTS_DIR: charts-ref + UMBRELLA_CHARTS: ./sdcore-helm-charts + steps: + - uses: actions/checkout@v4 + + - name: Set up Helm + uses: azure/setup-helm@v4 + with: + version: latest + token: ${{ secrets.GH_OMEC_PAT }} + + - name: Get current Index.yaml + run: | + rm -rf ${{ env.REF_CHARTS_DIR }} && mkdir -p ${{ env.REF_CHARTS_DIR }} + curl -o ${{ env.REF_CHARTS_DIR }}/index.yaml ${{ env.CHARTS_REPO_URL }}/index.yaml + + - name: Find all Charts and Package them + run: | + rm -rf ${{ env.CHARTS_DIR }} && mkdir -p ${{ env.CHARTS_DIR }} + for dir in $(find . -maxdepth 1 -mindepth 1 -type d); do + if [[ -f "$dir/Chart.yaml" ]] && [[ "$dir" != ${{ env.UMBRELLA_CHARTS }} ]]; then + echo "Packaging charts for: $dir" + helm dependency update "$dir" + helm package "$dir" --destination ${{ env.CHARTS_DIR }} + fi + done + helm repo index ${{ env.CHARTS_DIR }} --url ${{ env.CHARTS_REPO_URL }} --merge ${{ env.REF_CHARTS_DIR }}/index.yaml + + - name: Remove not "updated" local Charts (version has not changed) + working-directory: ${{ env.CHARTS_DIR }} + run: | + for file in *.tgz; do + if grep -q "${{ env.CHARTS_REPO_URL }}/$file" "../${{ env.REF_CHARTS_DIR }}/index.yaml"; then + echo "Not publishing $file because it is already in ${{ env.CHARTS_REPO_URL }}/index.yaml" + rm $file + fi + done + + - name: rsync deployments + uses: burnett01/rsync-deployments@7.0.1 + with: + switches: -avh + path: ${{ env.CHARTS_DIR }}/ + remote_path: /srv/sites/charts.aetherproject.org/ + remote_host: static.opennetworking.org + remote_user: ${{ secrets.JENKINS_USERNAME }} + remote_key: ${{ secrets.JENKINS_SSHKEY }} + remote_key_pass: ${{ secrets.JENKINS_PASSPHRASE }} + + - name: Get current Index.yaml + run: | + rm -rf ${{ env.REF_CHARTS_DIR }} && mkdir -p ${{ env.REF_CHARTS_DIR }} + curl -o ${{ env.REF_CHARTS_DIR }}/index.yaml ${{ env.CHARTS_REPO_URL }}/index.yaml + + - name: Find all Charts and Package them + run: | + rm -rf ${{ env.CHARTS_DIR }} && mkdir -p ${{ env.CHARTS_DIR }} + echo "Packaging charts for: ${{ env.UMBRELLA_CHARTS }}" + helm dependency update "${{ env.UMBRELLA_CHARTS }}" + helm package "${{ env.UMBRELLA_CHARTS }}" --destination ${{ env.CHARTS_DIR }} + helm repo index ${{ env.CHARTS_DIR }} --url ${{ env.CHARTS_REPO_URL }} --merge ${{ env.REF_CHARTS_DIR }}/index.yaml + + - name: rsync deployments + uses: burnett01/rsync-deployments@7.0.1 + with: + switches: -avh + path: ${{ env.CHARTS_DIR }}/ + remote_path: /srv/sites/charts.aetherproject.org/ + remote_host: static.opennetworking.org + remote_user: ${{ secrets.JENKINS_USERNAME }} + remote_key: ${{ secrets.JENKINS_SSHKEY }} + remote_key_pass: ${{ secrets.JENKINS_PASSPHRASE }} + + update-version: + runs-on: ubuntu-latest + needs: tag-github + if: needs.tag-github.outputs.changed == 'true' + steps: + - uses: actions/checkout@v4 + + - name: Increment version + run: | + version=${{ needs.tag-github.outputs.version }} + IFS='.' read -r major minor patch <<< "$version" + minor_update=$((minor+1)) + NEW_VERSION="$major.$minor_update.0-dev" + echo $NEW_VERSION > VERSION + echo "Updated version: $NEW_VERSION" + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v7 + with: + token: ${{ secrets.GH_OMEC_PAT }} + commit-message: Update version + committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + author: ${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com> + signoff: true + branch: version-update + delete-branch: true + title: Update version + body: | + Update VERSION file + add-paths: | + VERSION diff --git a/.github/workflows/release-helm-charts.yml b/.github/workflows/release-helm-charts.yml new file mode 100644 index 0000000..60a9804 --- /dev/null +++ b/.github/workflows/release-helm-charts.yml @@ -0,0 +1,167 @@ +--- +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2024 Intel Corporation +# Copyright 2024 Kyunghee University +# Copyright 2025 The Linux Foundation + +name: Publish image and tag/release code + +# yamllint disable-line rule:truthy +on: + workflow_call: + inputs: + CHARTS_REPO_URL: + description: "Repo URL to push charts to" + required: false + type: string + UMBRELLA_CHART: + description: "The repository's umbrella chart, if applicable" + required: false + type: string + RSYNC_REMOTE_HOST: + description: "The remote host to sync charts to" + required: false + type: string + RSYNC_REMOTE_PATH: + description: "The path on the remote host to sync charts to" + required: false + type: string + +jobs: + get-changed-charts-json: + runs-on: ubuntu-latest + outputs: + charts: ${{ steps.get-charts.outputs.charts_json }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Get charts + id: get-charts + uses: onos-project/.github/.github/actions/find-all-charts-action@main + + tag-github-vfile: + runs-on: ubuntu-latest + if: ${{ hashFiles('VERSION') != '' }} + outputs: + changed: ${{ steps.version-change.outputs.changed }} + version: ${{ steps.version-change.outputs.version }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get changed + id: version-file + run: | + if git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | grep VERSION; then + echo "changed=true" >> $GITHUB_OUTPUT + else + echo "VERSION file was not changed" + fi + + - name: Validate change in version file + id: version-change + if: steps.version-file.outputs.changed == 'true' + run: | + version=$(cat VERSION) + echo "version=$version" + validate="^[0-9]+\.[0-9]+\.[0-9]+$" + if [[ $version =~ $validate ]]; then + echo "changed=true" >> $GITHUB_OUTPUT + echo "version=$version" >> $GITHUB_OUTPUT + else + echo "Version change not for release" + fi + + - name: Create Github release + if: steps.version-change.outputs.changed == 'true' + uses: onos-project/.github/.github/actions/create-github-release-action@main + with: + version: ${{ steps.version-change.outputs.version }} + + version-check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Setup yq + uses: vegardit/gha-setup-yq@v1 + - name: Check all changed charts have unique versions + id: version-change + run: | + export COMPARISON_BRANCH=${{ github.event.before }} + ${{ github.action_path }}/version_check.sh check_unique + + tag-versions: + runs-on: ubuntu-latest + needs: [get-changed-charts-json, version-check] + if: github.repository_owner == 'onosproject' + strategy: + matrix: + chart: ${{ fromJson(needs.get-changed-charts-json.outputs.charts) }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Get chart version + id: get_chart_version + uses: onos-project/.github/.github/actions/get-chart-version-action@main + with: + CHART_PATH: ${{ matrix.chart }}/Chart.yaml + - name: Release chart version + uses: onos-project/.github/.github/actions/create-github-release-action@main + with: + version: ${{ steps.get_chart_version.outputs.version }} + + publish-charts: + runs-on: ubuntu-latest + needs: tag-versions + if: (github.repository_owner == 'onosproject') + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Setup yq + uses: vegardit/gha-setup-yq@v1 + - name: Setup Helm + uses: azure/setup-helm@v4 + with: + version: latest + token: ${{ secrets.GH_ONOS_PAT }} + - name: build + run: make deps + - name: Get charts + id: get-charts + uses: onos-project/.github/.github/actions/find-all-charts-action@main + - name: Publish all changed charts + # yamllint disable rule:line-length + run: | + export COMPARISON_BRANCH=${{ github.event.before }} + target_charts=${{ steps.get-charts.outputs.charts }} + rm -rf staging && mkdir -p staging/${{ github.repository }} + while IFS= read -r tc + do + mkdir -p staging/${{ github.repository }}/$tc + tc_ver=$(yq e '.version' $tc/Chart.yaml) + helm package $tc --destination staging/${{ github.repository }}/$tc + done <<< $target_charts + cd staging + curl -o current-index.yaml ${{ inputs.CHARTS_REPO_URL }}/index.yaml + helm repo index ${{ github.repository }} --url ${{ inputs.CHARTS_REPO_URL }}/${{ github.repository }} --merge current-index.yaml + rm -rf current-index.yaml + mv ${{ github.repository }}/index.yaml . + cd .. + chmod -R g+r staging/ + # yamllint enable rule:line-length + - name: rsync deployments + uses: burnett01/rsync-deployments@7.0.1 + with: + switches: -rvzh + path: staging/ + remote_path: ${{ inputs.RSYNC_REMOTE_PATH }} + remote_host: ${{ inputs.RSYNC_REMOTE_HOST }} + remote_user: ${{ secrets.JENKINS_USERNAME }} + remote_key: ${{ secrets.JENKINS_SSHKEY }} + remote_key_pass: ${{ secrets.JENKINS_PASSPHRASE }} diff --git a/workflows/release_tag.yml b/.github/workflows/release_tag.yml similarity index 100% rename from workflows/release_tag.yml rename to .github/workflows/release_tag.yml diff --git a/.github/workflows/tag-github.yml b/.github/workflows/tag-github.yml new file mode 100644 index 0000000..88fcbd1 --- /dev/null +++ b/.github/workflows/tag-github.yml @@ -0,0 +1,57 @@ +# Copyright 2025 Canonical Ltd. +# SPDX-FileCopyrightText: 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 +name: Tag GitHub +# Calling workflow should include "secrets: inherit" + +on: + workflow_call: + outputs: + changed: + description: "Whether the VERSION file changed" + value: ${{ jobs.tag-github.outputs.changed }} + version: + description: "The version for the release" + value: ${{ jobs.tag-github.outputs.version }} + +jobs: + tag-github: + runs-on: ubuntu-latest + outputs: + changed: ${{ steps.version-change.outputs.changed }} + version: ${{ steps.version-change.outputs.version }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get changed + id: version-file + run: | + if git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | grep VERSION; then + echo "changed=true" >> $GITHUB_OUTPUT + else + echo "VERSION file was not changed" + fi + + - name: Validate change in version file + id: version-change + if: steps.version-file.outputs.changed == 'true' + run: | + version=$(cat VERSION) + echo "version=$version" + validate="^[0-9]+\.[0-9]+\.[0-9]+$" + if [[ $version =~ $validate ]]; then + echo "changed=true" >> $GITHUB_OUTPUT + echo "version=$version" >> $GITHUB_OUTPUT + else + echo "Version change not for release" + fi + + - name: Create Github release + if: steps.version-change.outputs.changed == 'true' + uses: onos-project/.github/.github/actions/create-github-release-action@main + with: + version: ${{ steps.version-change.outputs.version }} + env: + GH_TOKEN: ${{ secrets.GH_ONOS_PAT }} diff --git a/.github/workflows/tox.ini b/.github/workflows/tox.ini new file mode 100644 index 0000000..e6dc8d5 --- /dev/null +++ b/.github/workflows/tox.ini @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: 2017 The Linux Foundation + +[tox] +minversion = 1.6 +envlist = + check-best-practices, + docs, + docs-linkcheck, + pre-commit +skipsdist=true + +[testenv] +basepython = python3 +install_command=python -m pip install --no-cache-dir {opts} {packages} + +[testenv:check-best-practices] +basepython = python3 +commands = python {toxinidir}/check-best-practices.py + +[testenv:docs] +basepython = python3 +deps = -rrequirements.txt +commands = + sphinx-build -q -j auto -W -b html -n -W -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/html + +[testenv:docs-linkcheck] +basepython = python3 +deps = -rrequirements.txt +commands = sphinx-build -q -j auto -W -b linkcheck -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/linkcheck + +[testenv:pre-commit] +basepython = python3 +allowlist_externals = + /bin/sh +deps = + pre-commit +passenv = HOME +commands = + pre-commit run --all-files --show-diff-on-failure + /bin/sh -c 'if ! git config --get user.name > /dev/null; then \ + git config --global --add user.name "CI"; \ + touch .git/REMOVE_USERNAME; fi' + /bin/sh -c 'if ! git config --get user.email > /dev/null; then \ + git config --global --add user.email "ci@example.org"; \ + touch .git/REMOVE_USEREMAIL; fi' + /bin/sh -c "if [ -f .git/COMMIT_EDITMSG ]; then \ + cp .git/COMMIT_EDITMSG .git/COMMIT_MSGTOX; else \ + git log HEAD -n1 | tail -n +5 | cut -c 5- > .git/COMMIT_MSGTOX; fi" + pre-commit run gitlint --hook-stage commit-msg --commit-msg-filename .git/COMMIT_MSGTOX + /bin/sh -c "rm -f .git/COMMIT_MSGTOX" + /bin/sh -c "if [ -f .git/REMOVE_USERNAME ]; then \ + git config --global --unset user.name; \ + rm -f .git/REMOVE_USERNAME; fi" + /bin/sh -c "if [ -f .git/REMOVE_USEREMAIL ]; then \ + git config --global --unset user.email; \ + rm -f .git/REMOVE_USEREMAIL; fi" diff --git a/.github/workflows/version_check.sh b/.github/workflows/version_check.sh new file mode 100755 index 0000000..b2b4dbd --- /dev/null +++ b/.github/workflows/version_check.sh @@ -0,0 +1,81 @@ +#!/bin/bash +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2024 Intel Corporation +# Copyright 2024 The Linux Foundation + +INPUT=$1 + +COMPARISON_BRANCH="${COMPARISON_BRANCH:-master}" + +function is_valid_format() { + # check if version format is matched to SemVer + VER_REGEX='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$' + if [[ ! $(echo $1 | tr -d '\n' | sed s/-dev//) =~ $VER_REGEX ]] + then + echo Version $1 is not in SemVer + return 1 + fi + return 0 +} + +function get_changed_charts() { + while IFS= read -r -d '' chart + do + chart_dir=$(dirname $chart) + chart_dir=$(basename $chart_dir) + chart_diff=$(git diff -p $COMPARISON_BRANCH --name-only ./$chart_dir) + if [ -n "$chart_diff" ] + then + echo $chart_dir + fi + done < <(find . -name Chart.yaml -print0) +} + +function is_unique_version() { + echo "comparison branch $COMPARISON_BRANCH" + + while IFS= read -r -d '' chart + do + chart_dir=$(dirname $chart) + chart_dir=$(basename $chart_dir) + chart_diff=$(git diff -p $COMPARISON_BRANCH --name-only ./$chart_dir) + + if [ -n "$chart_diff" ] + then + chart_ver=$(yq e '.version' ${chart_dir}/Chart.yaml) + + is_valid_format $chart_ver + if [ $? == 1 ] + then + echo $chart_dir does not have SemVer formatted version $chart_ver + return 1 + fi + + for t in $(git tag | grep $chart_dir | cat) + do + pure_t=$(echo $t | sed s/$chart_dir-//) + if [ "$pure_t" == "$chart_ver" ] + then + echo Chart $chart_dir version duplicated $chart_ver=$pure_t + return 1 + fi + done + fi + done < <(find . -name Chart.yaml -print0) + return 0 +} + +case $INPUT in + check_unique) + is_unique_version + ;; + + get_changed_charts) + get_changed_charts + ;; + + *) + echo -n "unknown input" + exit 2 + ;; +esac diff --git a/workflows/release-helm-charts.yml b/workflows/release-helm-charts.yml deleted file mode 100644 index ee15d50..0000000 --- a/workflows/release-helm-charts.yml +++ /dev/null @@ -1,110 +0,0 @@ ---- -# SPDX-License-Identifier: Apache-2.0 -# Copyright 2024 Intel Corporation -# Copyright 2024 Kyunghee University -# Copyright 2024 The Linux Foundation - -name: Publish image and tag/release code - -# yamllint disable-line rule:truthy -on: - workflow_call: - -jobs: - version-check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Setup yq - uses: vegardit/gha-setup-yq@v1 - - name: check version - run: | - export COMPARISON_BRANCH=origin/master - git branch -a - ${{ github.action_path }}/version_check.sh all - - tag_versions: - runs-on: ubuntu-latest - needs: version-check - if: github.repository_owner == 'onosproject' - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Setup yq - uses: vegardit/gha-setup-yq@v1 - - name: create release using REST API - # yamllint disable rule:line-length - run: | - export COMPARISON_BRANCH=${{ github.event.before }} - target_charts=$(${{ github.action_path }}/version_check.sh get_changed_charts) - while IFS= read -r tc - do - tc_ver=$(yq e '.version' $tc/Chart.yaml) - tag_name=$tc-$tc_ver - curl -L \ - -X POST \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${{ secrets.GH_ONOS_PAT }}" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/repos/${{ github.repository }}/releases \ - -d '{ - "tag_name": "'"$tag_name"'", - "target_commitish": "${{ github.event.repository.default_branch }}", - "name": "'"$tag_name"'", - "draft": false, - "prerelease": false, - "generate_release_notes": true - }' - done <<< $target_charts - # yamllint enable rule:line-length - - publish-charts: - runs-on: ubuntu-latest - needs: version-check - if: (github.repository_owner == 'onosproject') - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Setup yq - uses: vegardit/gha-setup-yq@v1 - - name: Setup Helm - uses: azure/setup-helm@v4 - with: - version: latest - token: ${{ secrets.GH_ONOS_PAT }} - - name: build - run: make deps - - name: publish charts - # yamllint disable rule:line-length - run: | - export COMPARISON_BRANCH=${{ github.event.before }} - target_charts=$(${{ github.action_path }}/version_check.sh get_changed_charts) - rm -rf staging && mkdir -p staging/onos-helm-charts - while IFS= read -r tc - do - mkdir -p staging/onos-helm-charts/$tc - tc_ver=$(yq e '.version' $tc/Chart.yaml) - helm package $tc --destination staging/onos-helm-charts/$tc - done <<< $target_charts - cd staging - curl -o current-index.yaml https://charts.onosproject.org/index.yaml - helm repo index onos-helm-charts --url https://charts.onosproject.org/onos-helm-charts --merge current-index.yaml - rm -rf current-index.yaml - mv onos-helm-charts/index.yaml . - cd .. - chmod -R g+r staging/ - # yamllint enable rule:line-length - - name: rsync deployments - uses: burnett01/rsync-deployments@7.0.1 - with: - switches: -rvzh - path: staging/ - remote_path: /srv/sites/charts.onosproject.org - remote_host: static.opennetworking.org - remote_user: ${{ secrets.JENKINS_USERNAME }} - remote_key: ${{ secrets.JENKINS_SSHKEY }} - remote_key_pass: ${{ secrets.JENKINS_PASSPHRASE }}