tekton: automate releases with Pipelines-as-Code#1656
Open
ab-ghosh wants to merge 1 commit into
Open
Conversation
Signed-off-by: ab-ghosh <abghosh@redhat.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
| steps: | ||
| - name: Validate inputs | ||
| run: | | ||
| if [[ ! "${{ inputs.branch }}" =~ ^release-v[0-9]+\.[0-9]+\.x$ ]]; then |
| - name: Validate inputs | ||
| run: | | ||
| if [[ ! "${{ inputs.branch }}" =~ ^release-v[0-9]+\.[0-9]+\.x$ ]]; then | ||
| echo "::error::Invalid branch format: ${{ inputs.branch }}. Expected: release-vX.Y.x" |
| echo "::error::Invalid branch format: ${{ inputs.branch }}. Expected: release-vX.Y.x" | ||
| exit 1 | ||
| fi | ||
| if [[ ! "${{ inputs.version }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then |
| exit 1 | ||
| fi | ||
| if [[ ! "${{ inputs.version }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | ||
| echo "::error::Invalid version format: ${{ inputs.version }}. Expected: vX.Y.Z" |
| env: | ||
| PAC_INCOMING_SECRET: ${{ secrets.PAC_INCOMING_SECRET }} | ||
| run: | | ||
| echo "::notice::Triggering release ${{ inputs.version }} on ${{ inputs.branch }} (latest=${{ inputs.release_as_latest }})" |
| -H "Content-Type: application/json" \ | ||
| -d '{ | ||
| "repository": "'"${PAC_REPOSITORY_NAME}"'", | ||
| "branch": "${{ inputs.branch }}", |
| "pipelinerun": "release-patch", | ||
| "secret": "'"${PAC_INCOMING_SECRET}"'", | ||
| "params": { | ||
| "version": "${{ inputs.version }}", |
Comment on lines
+30
to
+113
| scan-release-branches: | ||
| name: Scan for unreleased commits | ||
| if: github.event_name == 'schedule' && github.repository_owner == 'tektoncd' | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| matrix: ${{ steps.scan.outputs.matrix }} | ||
| has_releases: ${{ steps.scan.outputs.has_releases }} | ||
| steps: | ||
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Scan release branches for new commits | ||
| id: scan | ||
| run: | | ||
| # Determine which release branch is the latest (highest version) | ||
| latest_branch="" | ||
| latest_major=0 | ||
| latest_minor=0 | ||
| for ref in $(git branch -r --list 'origin/release-v*'); do | ||
| branch="${ref#origin/}" | ||
| if [[ "$branch" =~ release-v([0-9]+)\.([0-9]+)\.x ]]; then | ||
| major="${BASH_REMATCH[1]}" | ||
| minor="${BASH_REMATCH[2]}" | ||
| if [ "$major" -gt "$latest_major" ] || { [ "$major" -eq "$latest_major" ] && [ "$minor" -gt "$latest_minor" ]; }; then | ||
| latest_major=$major | ||
| latest_minor=$minor | ||
| latest_branch=$branch | ||
| fi | ||
| fi | ||
| done | ||
| echo "::notice::Latest release branch: ${latest_branch}" | ||
|
|
||
| MIN_MAJOR="${MIN_RELEASE_VERSION%%.*}" | ||
| MIN_MINOR="${MIN_RELEASE_VERSION##*.}" | ||
|
|
||
| releases=() | ||
| for ref in $(git branch -r --list 'origin/release-v*'); do | ||
| branch="${ref#origin/}" | ||
|
|
||
| # Skip branches older than MIN_RELEASE_VERSION | ||
| if [[ "$branch" =~ release-v([0-9]+)\.([0-9]+)\.x ]]; then | ||
| major="${BASH_REMATCH[1]}" | ||
| minor="${BASH_REMATCH[2]}" | ||
| if [ "$major" -lt "$MIN_MAJOR" ] || { [ "$major" -eq "$MIN_MAJOR" ] && [ "$minor" -lt "$MIN_MINOR" ]; }; then | ||
| echo "::notice::Branch ${branch} is older than v${MIN_RELEASE_VERSION} — skipping" | ||
| continue | ||
| fi | ||
| fi | ||
|
|
||
| # Find the latest tag on this branch | ||
| last_tag=$(git describe --tags --abbrev=0 --match 'v*' "$ref" 2>/dev/null || echo "") | ||
| if [ -z "$last_tag" ]; then | ||
| echo "::notice::Branch ${branch} has no tags — skipping (initial release handled by branch creation)" | ||
| continue | ||
| fi | ||
|
|
||
| # Count commits since last tag | ||
| new_commits=$(git rev-list "${last_tag}..${ref}" --count) | ||
| if [ "$new_commits" -eq 0 ]; then | ||
| echo "::notice::Branch ${branch} has no new commits since ${last_tag}" | ||
| continue | ||
| fi | ||
|
|
||
| # Calculate next patch version: v0.26.3 → v0.26.4 | ||
| next_version=$(echo "$last_tag" | awk -F. '{printf "%s.%s.%d", $1, $2, $3+1}') | ||
|
|
||
| # Only the latest release branch publishes as latest | ||
| is_latest="false" | ||
| if [ "$branch" = "$latest_branch" ]; then | ||
| is_latest="true" | ||
| fi | ||
|
|
||
| echo "::notice::Branch ${branch}: ${new_commits} new commits since ${last_tag} → ${next_version} (latest=${is_latest})" | ||
| releases+=("{\"branch\":\"${branch}\",\"version\":\"${next_version}\",\"release_as_latest\":\"${is_latest}\"}") | ||
| done | ||
|
|
||
| if [ ${#releases[@]} -eq 0 ]; then | ||
| echo "matrix=[]" >> "$GITHUB_OUTPUT" | ||
| echo "has_releases=false" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "matrix=[$(IFS=,; echo "${releases[*]}")]" >> "$GITHUB_OUTPUT" | ||
| echo "has_releases=true" >> "$GITHUB_OUTPUT" | ||
| fi |
Comment on lines
+115
to
+142
| trigger-scanned-releases: | ||
| name: "Trigger ${{ matrix.release.version }} (${{ matrix.release.branch }})" | ||
| needs: scan-release-branches | ||
| if: needs.scan-release-branches.outputs.has_releases == 'true' | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| matrix: | ||
| release: ${{ fromJson(needs.scan-release-branches.outputs.matrix) }} | ||
| max-parallel: 1 | ||
| steps: | ||
| - name: Trigger PAC incoming webhook | ||
| env: | ||
| PAC_INCOMING_SECRET: ${{ secrets.PAC_INCOMING_SECRET }} | ||
| run: | | ||
| echo "::notice::Triggering release ${{ matrix.release.version }} on ${{ matrix.release.branch }} (latest=${{ matrix.release.release_as_latest }})" | ||
| curl -sf -X POST "${PAC_CONTROLLER_URL}/incoming" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{ | ||
| "repository": "'"${PAC_REPOSITORY_NAME}"'", | ||
| "branch": "${{ matrix.release.branch }}", | ||
| "pipelinerun": "release-patch", | ||
| "secret": "'"${PAC_INCOMING_SECRET}"'", | ||
| "params": { | ||
| "version": "${{ matrix.release.version }}", | ||
| "release_as_latest": "${{ matrix.release.release_as_latest }}" | ||
| } | ||
| }' | ||
| echo "Release triggered successfully" |
Comment on lines
+38
to
+40
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||
| with: | ||
| fetch-depth: 0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes
Automate releases using Pipelines-as-Code instead of manual
tkn pipeline startcommands.What's included
.tekton/release.yaml— Initial release PipelineRun, triggered automatically when arelease-v*branch is created. Version derived from branch name via CEL (release-v0.27.x→v0.27.0)..tekton/release-patch.yaml— Patch release PipelineRun, triggered via PAC incoming webhook. Version andreleaseAsLatestpassed dynamically..github/workflows/patch-release.yaml— GitHub Actions workflow with two modes:workflow_dispatch: manual trigger with branch/version inputsschedule: weekly cron (Thursday 10:00 UTC) scanning for unreleased commits on release branches ≥ v0.20release/README.md— reflects the new automated workflow, with manualtkncommand preserved as a fallback section.Dependencies
releases-chainsnamespace (tektoncd/infra)tekton-as-codeinstalled on this repoPAC_INCOMING_SECRETGitHub Actions secret configuredSee tektoncd/plumbing#58 for the
full automated release plan.
/kind feature
Submitter Checklist
As the author of this PR, please check off the items in this checklist:
functionality, content, code)
Release Notes
Jira: SRVKP-11937