Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/actions/ios-fastlane-beta/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ inputs:
app_store_connect_api_key_issuer_id:
description: 'App Store Connect API Key Issuer ID'
required: true
build_number:
description: 'Custom build number. Skips auto-increment from TestFlight.'
required: false
version_number:
description: 'Custom version number. Overrides default.'
required: false
custom_values:
description: 'Custom values'
required: false
Expand All @@ -37,6 +43,8 @@ runs:
APP_STORE_CONNECT_API_KEY_KEY: ${{ inputs.app_store_connect_api_key_key }}
APP_STORE_CONNECT_API_KEY_KEY_ID: ${{ inputs.app_store_connect_api_key_key_id }}
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ inputs.app_store_connect_api_key_issuer_id }}
BUILD_NUMBER: ${{ inputs.build_number }}
VERSION_NUMBER: ${{ inputs.version_number }}
CUSTOM_VALUES: ${{ inputs.custom_values }}
IOS_ROOT_PATH: ${{ inputs.ios_root_path }}
CUSTOM_BUILD_PATH: ${{ inputs.custom_build_path }}
7 changes: 6 additions & 1 deletion .github/actions/ios-fastlane-beta/beta.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,10 @@ if [ -n "$CUSTOM_BUILD_PATH" ]; then
cd $GITHUB_WORKSPACE/$CUSTOM_BUILD_PATH
fi

# Build fastlane arguments from optional overrides
fastlane_args=()
[ -n "$BUILD_NUMBER" ] && fastlane_args+=("build_number:$BUILD_NUMBER")
[ -n "$VERSION_NUMBER" ] && fastlane_args+=("version_number:$VERSION_NUMBER")

# Environment variables are already set by action.yml
bundle exec fastlane beta
bundle exec fastlane beta "${fastlane_args[@]}"
29 changes: 29 additions & 0 deletions .github/actions/ios-fastlane-beta/test/test_beta.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bats

load test_helper

SCRIPT="$BATS_TEST_DIRNAME/../beta.sh"

@test "no overrides — runs fastlane beta without args" {
BUILD_NUMBER="" VERSION_NUMBER="" run bash "$SCRIPT"
[ "$status" -eq 0 ]
grep -q "^exec fastlane beta$" "$BUNDLE_LOG"
}

@test "BUILD_NUMBER set — passes build_number arg" {
BUILD_NUMBER="42" VERSION_NUMBER="" run bash "$SCRIPT"
[ "$status" -eq 0 ]
grep -q "^exec fastlane beta build_number:42$" "$BUNDLE_LOG"
}

@test "VERSION_NUMBER set — passes version_number arg" {
BUILD_NUMBER="" VERSION_NUMBER="1.2.0" run bash "$SCRIPT"
[ "$status" -eq 0 ]
grep -q "^exec fastlane beta version_number:1.2.0$" "$BUNDLE_LOG"
}

@test "both set — passes both args" {
BUILD_NUMBER="42" VERSION_NUMBER="1.2.0" run bash "$SCRIPT"
[ "$status" -eq 0 ]
grep -q "^exec fastlane beta build_number:42 version_number:1.2.0$" "$BUNDLE_LOG"
}
27 changes: 27 additions & 0 deletions .github/actions/ios-fastlane-beta/test/test_helper.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
setup() {
MOCK_DIR="$(mktemp -d)"
export PATH="$MOCK_DIR:$PATH"

# Mock gem command (no-op)
cat > "$MOCK_DIR/gem" <<'MOCK'
#!/bin/bash
exit 0
MOCK
chmod +x "$MOCK_DIR/gem"

# Mock bundle command — capture the full invocation
BUNDLE_LOG="$(mktemp)"
export BUNDLE_LOG
cat > "$MOCK_DIR/bundle" <<MOCK
#!/bin/bash
if [ "\$1" = "exec" ]; then
echo "\$@" >> "$BUNDLE_LOG"
fi
exit 0
MOCK
chmod +x "$MOCK_DIR/bundle"
}

teardown() {
rm -rf "$MOCK_DIR" "$BUNDLE_LOG"
}
14 changes: 12 additions & 2 deletions .github/actions/ios-fastlane-release/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ inputs:
description: 'Match password'
required: true
version_number:
description: 'Version number'
description: 'Version number (x.y.z format, any suffix after - is ignored)'
required: false
build_number:
description: 'Custom build number. Skips auto-increment from TestFlight.'
required: false
app_store_connect_api_key_key:
description: 'App Store Connect API Key'
Expand All @@ -28,12 +31,19 @@ inputs:
runs:
using: 'composite'
steps:
- name: Parse version tag
id: parse_version
shell: bash
run: ${{ github.action_path }}/parse-version-tag.sh
env:
VERSION_TAG: ${{ inputs.version_number }}
- name: Run release script
shell: bash
run: ${{ github.action_path }}/release.sh
env:
MATCH_PASSWORD: ${{ inputs.match_password }}
VERSION_NUMBER: ${{ inputs.version_number }}
VERSION_NUMBER: ${{ steps.parse_version.outputs.version_number }}
BUILD_NUMBER: ${{ inputs.build_number }}
APP_STORE_CONNECT_API_KEY_KEY: ${{ inputs.app_store_connect_api_key_key }}
APP_STORE_CONNECT_API_KEY_KEY_ID: ${{ inputs.app_store_connect_api_key_key_id }}
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ inputs.app_store_connect_api_key_issuer_id }}
Expand Down
11 changes: 11 additions & 0 deletions .github/actions/ios-fastlane-release/parse-version-tag.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash
set -e

TAG="$VERSION_TAG"

if [[ "$TAG" =~ ^([0-9]+\.[0-9]+\.[0-9]+)(-.*)?$ ]]; then
echo "version_number=${BASH_REMATCH[1]}" >> "$GITHUB_OUTPUT"
else
echo "::error::Tag '$TAG' does not match expected format 'x.y.z' or 'x.y.z-*' (any suffix after - is ignored)"
exit 1
fi
7 changes: 6 additions & 1 deletion .github/actions/ios-fastlane-release/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,10 @@ if [ -n "$CUSTOM_BUILD_PATH" ]; then
cd $GITHUB_WORKSPACE/$CUSTOM_BUILD_PATH
fi

# Build fastlane arguments from optional overrides
fastlane_args=()
[ -n "$BUILD_NUMBER" ] && fastlane_args+=("build_number:$BUILD_NUMBER")
[ -n "$VERSION_NUMBER" ] && fastlane_args+=("version_number:$VERSION_NUMBER")

# Environment variables are already set by action.yml
bundle exec fastlane release
bundle exec fastlane release "${fastlane_args[@]}"
8 changes: 8 additions & 0 deletions .github/actions/ios-fastlane-release/test/test_helper.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
setup() {
GITHUB_OUTPUT="$(mktemp)"
export GITHUB_OUTPUT
}

teardown() {
rm -f "$GITHUB_OUTPUT"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env bats

load test_helper

SCRIPT="$BATS_TEST_DIRNAME/../parse-version-tag.sh"

@test "parses simple version tag 1.0.0" {
VERSION_TAG="1.0.0" run bash "$SCRIPT"
[ "$status" -eq 0 ]
grep -q "^version_number=1.0.0$" "$GITHUB_OUTPUT"
! grep -q "^build_number=" "$GITHUB_OUTPUT"
}

@test "parses version tag with suffix 1.2.3-42" {
VERSION_TAG="1.2.3-42" run bash "$SCRIPT"
[ "$status" -eq 0 ]
grep -q "^version_number=1.2.3$" "$GITHUB_OUTPUT"
! grep -q "^build_number=" "$GITHUB_OUTPUT"
}

@test "parses large version numbers 10.20.30-999" {
VERSION_TAG="10.20.30-999" run bash "$SCRIPT"
[ "$status" -eq 0 ]
grep -q "^version_number=10.20.30$" "$GITHUB_OUTPUT"
! grep -q "^build_number=" "$GITHUB_OUTPUT"
}

@test "parses version tag with zero suffix 1.0.0-0" {
VERSION_TAG="1.0.0-0" run bash "$SCRIPT"
[ "$status" -eq 0 ]
grep -q "^version_number=1.0.0$" "$GITHUB_OUTPUT"
! grep -q "^build_number=" "$GITHUB_OUTPUT"
}

@test "parses tag with pre-release suffix 1.0.0-beta.1" {
VERSION_TAG="1.0.0-beta.1" run bash "$SCRIPT"
[ "$status" -eq 0 ]
grep -q "^version_number=1.0.0$" "$GITHUB_OUTPUT"
! grep -q "^build_number=" "$GITHUB_OUTPUT"
}

@test "parses tag with trailing dash 1.2.3-" {
VERSION_TAG="1.2.3-" run bash "$SCRIPT"
[ "$status" -eq 0 ]
grep -q "^version_number=1.2.3$" "$GITHUB_OUTPUT"
! grep -q "^build_number=" "$GITHUB_OUTPUT"
}

@test "parses tag with text suffix 2.0.0-rc1" {
VERSION_TAG="2.0.0-rc1" run bash "$SCRIPT"
[ "$status" -eq 0 ]
grep -q "^version_number=2.0.0$" "$GITHUB_OUTPUT"
! grep -q "^build_number=" "$GITHUB_OUTPUT"
}

@test "rejects v-prefixed tag v1.0.0" {
VERSION_TAG="v1.0.0" run bash "$SCRIPT"
[ "$status" -eq 1 ]
}

@test "rejects incomplete version 1.0" {
VERSION_TAG="1.0" run bash "$SCRIPT"
[ "$status" -eq 1 ]
}

@test "rejects empty tag" {
VERSION_TAG="" run bash "$SCRIPT"
[ "$status" -eq 1 ]
}
57 changes: 57 additions & 0 deletions .github/actions/ios-fastlane-release/test/test_release.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env bats

load test_helper

SCRIPT="$BATS_TEST_DIRNAME/../release.sh"

setup() {
MOCK_DIR="$(mktemp -d)"
export PATH="$MOCK_DIR:$PATH"

# Mock gem command (no-op)
cat > "$MOCK_DIR/gem" <<'MOCK'
#!/bin/bash
exit 0
MOCK
chmod +x "$MOCK_DIR/gem"

# Mock bundle command — capture the full invocation
BUNDLE_LOG="$(mktemp)"
export BUNDLE_LOG
cat > "$MOCK_DIR/bundle" <<MOCK
#!/bin/bash
if [ "\$1" = "exec" ]; then
echo "\$@" >> "$BUNDLE_LOG"
fi
exit 0
MOCK
chmod +x "$MOCK_DIR/bundle"
}

teardown() {
rm -rf "$MOCK_DIR" "$BUNDLE_LOG"
}

@test "no overrides — runs fastlane release without args" {
BUILD_NUMBER="" VERSION_NUMBER="" run bash "$SCRIPT"
[ "$status" -eq 0 ]
grep -q "^exec fastlane release$" "$BUNDLE_LOG"
}

@test "BUILD_NUMBER set — passes build_number arg" {
BUILD_NUMBER="42" VERSION_NUMBER="" run bash "$SCRIPT"
[ "$status" -eq 0 ]
grep -q "^exec fastlane release build_number:42$" "$BUNDLE_LOG"
}

@test "VERSION_NUMBER set — passes version_number arg" {
BUILD_NUMBER="" VERSION_NUMBER="1.2.0" run bash "$SCRIPT"
[ "$status" -eq 0 ]
grep -q "^exec fastlane release version_number:1.2.0$" "$BUNDLE_LOG"
}

@test "both set — passes both args" {
BUILD_NUMBER="42" VERSION_NUMBER="1.2.0" run bash "$SCRIPT"
[ "$status" -eq 0 ]
grep -q "^exec fastlane release build_number:42 version_number:1.2.0$" "$BUNDLE_LOG"
}
10 changes: 10 additions & 0 deletions .github/workflows/ios-selfhosted-on-demand-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ on:
type: string
required: false
# Custom values
build_number:
description: 'Custom build number. Skips auto-increment from TestFlight.'
type: string
required: false
version_number:
description: 'Custom version number. Overrides default (1.0.0).'
type: string
required: false
custom_values:
description: 'Custom string that can contains values specified in your workflow file. Those values will be placed into environment variable. Example: "CUSTOM-1: 1; CUSTOM-2: 2"'
type: string
Expand Down Expand Up @@ -110,6 +118,8 @@ jobs:
APP_STORE_CONNECT_API_KEY_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY }}
APP_STORE_CONNECT_API_KEY_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY_ID }}
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
build_number: ${{ inputs.build_number }}
version_number: ${{ inputs.version_number }}
custom_values: ${{ inputs.custom_values }}

- name: Upload IPA
Expand Down
Loading
Loading