Unsigned Internal RC #4
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
| name: Unsigned Internal RC | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| release_tag: | |
| description: "Existing tag to publish, for example v2.0.0" | |
| required: true | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: release-${{ inputs.release_tag }} | |
| cancel-in-progress: false | |
| jobs: | |
| build: | |
| runs-on: macos-26 | |
| outputs: | |
| tag_name: ${{ steps.release_tag.outputs.tag_name }} | |
| steps: | |
| - name: Check Out | |
| uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Resolve Release Tag | |
| id: release_tag | |
| env: | |
| MANUAL_RELEASE_TAG: ${{ inputs.release_tag }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| TAG_NAME="${MANUAL_RELEASE_TAG}" | |
| if [[ ! "$TAG_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| echo "Release tag must use vMAJOR.MINOR.PATCH: ${TAG_NAME}" >&2 | |
| exit 1 | |
| fi | |
| git fetch --force --tags origin | |
| git fetch --force origin main:refs/remotes/origin/main | |
| if ! git rev-parse --verify "refs/tags/${TAG_NAME}" >/dev/null 2>&1; then | |
| echo "Release tag ${TAG_NAME} does not exist. Create it before dispatching this workflow." >&2 | |
| exit 1 | |
| fi | |
| TAG_SHA="$(git rev-list -n 1 "refs/tags/${TAG_NAME}")" | |
| MAIN_SHA="$(git rev-parse refs/remotes/origin/main)" | |
| if [[ "$TAG_SHA" != "$MAIN_SHA" ]]; then | |
| echo "Release tag ${TAG_NAME} must point to the current origin/main commit." >&2 | |
| exit 1 | |
| fi | |
| git checkout --detach "$TAG_SHA" | |
| if [[ ! -f "docs/releases/${TAG_NAME#v}.md" ]]; then | |
| echo "Release notes for ${TAG_NAME} are missing." >&2 | |
| exit 1 | |
| fi | |
| echo "tag_name=${TAG_NAME}" >> "$GITHUB_OUTPUT" | |
| - name: Check Source Version | |
| run: python3 scripts/check_release_version.py --tag "${{ steps.release_tag.outputs.tag_name }}" | |
| - name: Set Up Xcode | |
| uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0 | |
| with: | |
| xcode-version: latest-stable | |
| - name: Set Up Node | |
| uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: "20" | |
| cache: npm | |
| cache-dependency-path: tui/package-lock.json | |
| - name: Install TUI Dependencies | |
| working-directory: tui | |
| run: npm ci | |
| - name: Build TUI | |
| working-directory: tui | |
| run: npm run build | |
| - name: Resolve Swift Packages | |
| run: | | |
| xcodebuild \ | |
| -resolvePackageDependencies \ | |
| -project SkillsManager.xcodeproj \ | |
| -scheme SkillsManager | |
| - name: Test App | |
| run: | | |
| xcodebuild \ | |
| -project SkillsManager.xcodeproj \ | |
| -scheme SkillsManager \ | |
| -configuration Debug \ | |
| -destination "platform=macOS" \ | |
| CODE_SIGNING_ALLOWED=NO \ | |
| test | |
| - name: Analyze App | |
| run: | | |
| xcodebuild \ | |
| -project SkillsManager.xcodeproj \ | |
| -scheme SkillsManager \ | |
| -configuration Debug \ | |
| -destination "platform=macOS" \ | |
| CODE_SIGNING_ALLOWED=NO \ | |
| analyze | |
| - name: Build Release App | |
| env: | |
| DERIVED_DATA: ${{ runner.temp }}/DerivedData | |
| run: | | |
| xcodebuild \ | |
| -project SkillsManager.xcodeproj \ | |
| -scheme SkillsManager \ | |
| -configuration Release \ | |
| -destination "platform=macOS" \ | |
| -derivedDataPath "$DERIVED_DATA" \ | |
| CODE_SIGNING_ALLOWED=NO \ | |
| build | |
| - name: Package App | |
| id: package | |
| env: | |
| DERIVED_DATA: ${{ runner.temp }}/DerivedData | |
| TAG_NAME: ${{ steps.release_tag.outputs.tag_name }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| APP_PATH="$(find "$DERIVED_DATA/Build/Products/Release" -maxdepth 1 -name 'Skills Manager.app' -print -quit)" | |
| if [[ -z "$APP_PATH" ]]; then | |
| echo "Release app not found" >&2 | |
| exit 1 | |
| fi | |
| python3 "${GITHUB_WORKSPACE}/scripts/check_release_version.py" \ | |
| --tag "$TAG_NAME" \ | |
| --app "$APP_PATH" | |
| ZIP_PATH="$RUNNER_TEMP/SkillsManager-${TAG_NAME}-unsigned-internal-rc.zip" | |
| NOTES_PATH="$RUNNER_TEMP/release-notes.md" | |
| ditto -c -k --sequesterRsrc --keepParent "$APP_PATH" "$ZIP_PATH" | |
| cp "$GITHUB_WORKSPACE/docs/releases/${TAG_NAME#v}.md" "$NOTES_PATH" | |
| echo "zip_path=$ZIP_PATH" >> "$GITHUB_OUTPUT" | |
| echo "notes_path=$NOTES_PATH" >> "$GITHUB_OUTPUT" | |
| - name: Stage Unsigned RC | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: unsigned-internal-rc | |
| path: | | |
| ${{ steps.package.outputs.zip_path }} | |
| ${{ steps.package.outputs.notes_path }} | |
| if-no-files-found: error | |
| retention-days: 14 | |
| publish: | |
| needs: build | |
| runs-on: ubuntu-latest | |
| environment: release | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Download Unsigned RC | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 | |
| with: | |
| name: unsigned-internal-rc | |
| path: ${{ runner.temp }}/release | |
| - name: Publish GitHub Prerelease | |
| uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 | |
| with: | |
| tag_name: ${{ needs.build.outputs.tag_name }} | |
| name: Skills Manager ${{ needs.build.outputs.tag_name }} unsigned internal RC | |
| prerelease: true | |
| body_path: ${{ runner.temp }}/release/release-notes.md | |
| files: ${{ runner.temp }}/release/*.zip |