1919jobs :
2020 release-packager :
2121 permissions :
22+ contents : write
23+ pull-requests : write
2224 id-token : write
2325 name : Release Packager
2426 runs-on : ubuntu-latest
3133 env :
3234 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
3335
36+ - name : Install GitHub CLI
37+ run : |
38+ command -v gh >/dev/null 2>&1 || {
39+ curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
40+ sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg
41+ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
42+ sudo apt update
43+ sudo apt install gh
44+ }
45+
3446 # Currently FreeRTOS/.github/scripts houses the release script. Download it for upcoming usage
3547 - name : Checkout FreeRTOS Release Tools
3648 uses : actions/checkout@v4.1.1
@@ -52,15 +64,23 @@ jobs:
5264 git config --global user.name "$ACTOR"
5365 git config --global user.email "$ACTOR"@users.noreply.github.com
5466
55- - name : create a new branch that references commit id
67+ - name : Create version branch
5668 env :
5769 VERSION_NUMBER : ${{ github.event.inputs.version_number }}
5870 COMMIT_ID : ${{ github.event.inputs.commit_id }}
5971 working-directory : ./local_kernel
6072 run : |
6173 git checkout -b "$VERSION_NUMBER" "$COMMIT_ID"
74+ git push -u origin "$VERSION_NUMBER"
6275 echo "COMMIT_SHA_1=$(git rev-parse HEAD)" >> $GITHUB_ENV
6376
77+ - name : Create release preparation branch
78+ env :
79+ VERSION_NUMBER : ${{ github.event.inputs.version_number }}
80+ working-directory : ./local_kernel
81+ run : |
82+ git checkout -b "release-prep-$VERSION_NUMBER"
83+
6484 - name : Update source files with version info
6585 env :
6686 VERSION_NUMBER : ${{ github.event.inputs.version_number }}
@@ -73,37 +93,100 @@ jobs:
7393 ./tools/.github/scripts/update_src_version.py FreeRTOS --kernel-repo-path=local_kernel --kernel-commit="$COMMIT_SHA_1" --new-kernel-version="$VERSION_NUMBER" --new-kernel-main-br-version="$MAIN_BR_VERSION_NUMBER"
7494 exit $?
7595
76- - name : Update version number in manifest.yml
96+ - name : Update version number in manifest.yml
7797 env :
7898 VERSION_NUMBER : ${{ github.event.inputs.version_number }}
7999 working-directory : ./local_kernel
80100 run : |
81101 ./.github/scripts/manifest_updater.py -v "$VERSION_NUMBER"
82102 exit $?
83103
84- - name : Commit version number change in manifest.yml
104+ - name : Commit and push release preparation branch
85105 env :
86106 VERSION_NUMBER : ${{ github.event.inputs.version_number }}
87107 working-directory : ./local_kernel
88108 run : |
109+ # The update_src_version.py script detaches HEAD by checking out a SHA.
110+ # Re-attach HEAD to the release prep branch, keeping all commits.
111+ git branch -f "release-prep-$VERSION_NUMBER" HEAD
112+ git checkout "release-prep-$VERSION_NUMBER"
113+
89114 git add .
90- git commit -m '[AUTO][RELEASE]: Update version number in manifest.yml'
91- git push -u origin "$VERSION_NUMBER"
115+ if git diff --cached --quiet; then
116+ echo "No new changes to commit — source files and manifest already up to date."
117+ else
118+ git commit -m '[AUTO][RELEASE]: Update version number in manifest.yml and source files'
119+ fi
120+ git push -u origin "release-prep-$VERSION_NUMBER"
121+
122+ - name : Create pull request
123+ env :
124+ VERSION_NUMBER : ${{ github.event.inputs.version_number }}
125+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
126+ REPO_FULL_NAME : ${{ github.repository }}
127+ working-directory : ./local_kernel
128+ run : |
129+ PR_URL=$(gh pr create \
130+ --repo "$REPO_FULL_NAME" \
131+ --base "$VERSION_NUMBER" \
132+ --head "release-prep-$VERSION_NUMBER" \
133+ --title "[AUTO][RELEASE]: Release $VERSION_NUMBER" \
134+ --body "Automated release preparation for $VERSION_NUMBER. Updates version numbers in source files and manifest.yml.")
135+ echo "PR_URL=$PR_URL" >> $GITHUB_ENV
136+
137+ - name : Wait for PR to be merged
138+ env :
139+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
140+ REPO_FULL_NAME : ${{ github.repository }}
141+ working-directory : ./local_kernel
142+ run : |
143+ PR_NUMBER=$(echo "$PR_URL" | grep -oE '[0-9]+$')
144+ while true; do
145+ STATE=$(gh pr view "$PR_NUMBER" --repo "$REPO_FULL_NAME" --json state --jq .state)
146+ if [ "$STATE" = "MERGED" ]; then
147+ echo "PR merged successfully"
148+ break
149+ elif [ "$STATE" = "CLOSED" ]; then
150+ echo "Error: PR was closed without merging"
151+ exit 1
152+ fi
153+ echo "Waiting for PR to be merged... (current state: $STATE)"
154+ sleep 30
155+ done
156+
157+ - name : Re-checkout after merge
158+ uses : actions/checkout@v4.1.1
159+ with :
160+ path : local_kernel
161+ ref : ${{ github.event.inputs.version_number }}
162+ fetch-depth : 0
92163
93164 - name : Generate SBOM
94165 uses : FreeRTOS/CI-CD-Github-Actions/sbom-generator@main
95166 with :
96- repo_path : ./local_kernel
97- source_path : ./
167+ directory : ./local_kernel
168+ distribution-type : repository
169+ creator : Amazon Web Services, Inc.
170+ download-location : git+https://github.com/${{ github.repository_owner }}/${{ github.event.repository.name }}.git@${{ github.event.inputs.version_number }}
171+ homepage : https://github.com/${{ github.repository_owner }}/${{ github.event.repository.name }}
172+ namespace-prefix : https://github.com/${{ github.repository_owner }}/${{ github.event.repository.name }}/releases/download/V${{ github.event.inputs.version_number }}/
173+ include-file-hashes : true
98174
99- - name : commit SBOM file
175+ - name : Commit SBOM file
100176 env :
101177 VERSION_NUMBER : ${{ github.event.inputs.version_number }}
102- working-directory : ./local_kernel
178+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
103179 run : |
180+ # SBOM generator writes files to the workspace root — copy them into the repo
181+ cp *SPDX* ./local_kernel/ 2>/dev/null || cp *spdx* ./local_kernel/ 2>/dev/null || true
182+ cd ./local_kernel
104183 git add .
105- git commit -m '[AUTO][RELEASE]: Update SBOM'
106- git push -u origin "$VERSION_NUMBER"
184+ if git diff --cached --quiet; then
185+ echo "No SBOM changes to commit."
186+ else
187+ git commit -m '[AUTO][RELEASE]: Update SBOM'
188+ git push -u origin "$VERSION_NUMBER"
189+ fi
107190 echo "COMMIT_SHA_2=$(git rev-parse HEAD)" >> $GITHUB_ENV
108191
109192 - name : Release
@@ -125,12 +208,19 @@ jobs:
125208 # This is dependent on the release script putting this zip file
126209 # in this exact location.
127210 artifact_path : ./FreeRTOS-KernelV${{ github.event.inputs.version_number }}.zip
128- release_tag : ${{ github.event.inputs.version_number }}
211+ release_tag : V ${{ github.event.inputs.version_number }}
129212
130- - name : Cleanup
213+ - name : Delete release preparation branch
214+ if : always()
131215 env :
132216 VERSION_NUMBER : ${{ github.event.inputs.version_number }}
217+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
133218 working-directory : ./local_kernel
134219 run : |
135- # Delete the branch created for Tag by SBOM generator
136- git push -u origin --delete "$VERSION_NUMBER"
220+ # Only delete release-prep branch if the PR was already merged
221+ PR_STATE=$(gh pr list --repo "${{ github.repository }}" --head "release-prep-$VERSION_NUMBER" --json state --jq '.[0].state' 2>/dev/null || echo "")
222+ if [ "$PR_STATE" = "MERGED" ] || [ -z "$PR_STATE" ]; then
223+ git push origin --delete "release-prep-$VERSION_NUMBER" || true
224+ else
225+ echo "Skipping release-prep branch deletion — PR is still open (state: $PR_STATE)"
226+ fi
0 commit comments