ios: ci: deploy via fastlane
This commit is contained in:
187
.gitea/workflows/testflight-release.yml
Normal file
187
.gitea/workflows/testflight-release.yml
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
name: TestFlight Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "release/v*.*.*"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
testflight:
|
||||||
|
runs-on: xcode
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Validate release tag
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
tag_name="${GITHUB_REF#refs/tags/}"
|
||||||
|
if [[ ! "$tag_name" =~ ^release/v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||||
|
echo "Release tag must match release/vN.N.N; got ${tag_name}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
release_version="${tag_name#release/v}"
|
||||||
|
{
|
||||||
|
echo "TAG_NAME=${tag_name}"
|
||||||
|
echo "RELEASE_VERSION=${release_version}"
|
||||||
|
} >> "${GITHUB_ENV}"
|
||||||
|
|
||||||
|
- name: Set up Ruby
|
||||||
|
uses: ruby/setup-ruby@v1
|
||||||
|
with:
|
||||||
|
ruby-version: "3.3"
|
||||||
|
|
||||||
|
- name: Install Ruby gems
|
||||||
|
working-directory: ios
|
||||||
|
run: bundle install
|
||||||
|
|
||||||
|
- name: Install release tools
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
missing_tools=()
|
||||||
|
for tool in xcodegen jq; do
|
||||||
|
if ! command -v "${tool}" >/dev/null 2>&1; then
|
||||||
|
missing_tools+=("${tool}")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "${#missing_tools[@]}" -eq 0 ]]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v brew >/dev/null 2>&1; then
|
||||||
|
echo "Missing required tools: ${missing_tools[*]}; Homebrew is not available to install them" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
brew install "${missing_tools[@]}"
|
||||||
|
|
||||||
|
- name: Import code signing certificates
|
||||||
|
uses: Apple-Actions/import-codesign-certs@v3
|
||||||
|
with:
|
||||||
|
p12-file-base64: ${{ secrets.APPSTORE_CERTIFICATES_FILE_BASE64 }}
|
||||||
|
p12-password: ${{ secrets.APPSTORE_CERTIFICATES_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Create fastlane environment
|
||||||
|
working-directory: ios
|
||||||
|
env:
|
||||||
|
FASTLANE_USER: ${{ secrets.FASTLANE_USER }}
|
||||||
|
FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ secrets.FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
: "${FASTLANE_USER:?FASTLANE_USER secret is required}"
|
||||||
|
: "${FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD:?FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD secret is required}"
|
||||||
|
|
||||||
|
{
|
||||||
|
printf 'FASTLANE_USER=%s\n' "${FASTLANE_USER}"
|
||||||
|
printf 'FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD=%s\n' "${FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD}"
|
||||||
|
printf 'FASTLANE_SKIP_UPDATE_CHECK=1\n'
|
||||||
|
printf 'FASTLANE_HIDE_CHANGELOG=1\n'
|
||||||
|
} > .env
|
||||||
|
|
||||||
|
- name: Build and upload to TestFlight
|
||||||
|
working-directory: ios
|
||||||
|
env:
|
||||||
|
FASTLANE_DONT_STORE_PASSWORD: "1"
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SYBIL_VERSION_TAG="${TAG_NAME}" bundle exec fastlane ios beta
|
||||||
|
|
||||||
|
- name: Locate IPA
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ipa_path="$(find ios/build/fastlane -maxdepth 1 -type f -name '*.ipa' -print | sort | tail -n 1)"
|
||||||
|
if [[ -z "${ipa_path}" ]]; then
|
||||||
|
echo "No IPA found under ios/build/fastlane" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "IPA_PATH=${ipa_path}"
|
||||||
|
echo "IPA_NAME=$(basename "${ipa_path}")"
|
||||||
|
} >> "${GITHUB_ENV}"
|
||||||
|
|
||||||
|
- name: Publish Gitea release asset
|
||||||
|
env:
|
||||||
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
RELEASE_API_URL: ${{ github.api_url }}
|
||||||
|
RELEASE_REPOSITORY: ${{ github.repository }}
|
||||||
|
RELEASE_SHA: ${{ github.sha }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
: "${GITEA_TOKEN:?GITEA_TOKEN is required}"
|
||||||
|
|
||||||
|
api_url="${RELEASE_API_URL:-https://code.buzzert.dev/api/v1}"
|
||||||
|
repository="${RELEASE_REPOSITORY:-buzzert/Sybil-2}"
|
||||||
|
sha="${RELEASE_SHA:-${GITHUB_SHA:-}}"
|
||||||
|
release_name="Sybil v${RELEASE_VERSION}"
|
||||||
|
release_body="Automated TestFlight release for ${TAG_NAME}."
|
||||||
|
release_payload="$(jq -nc \
|
||||||
|
--arg tag "${TAG_NAME}" \
|
||||||
|
--arg name "${release_name}" \
|
||||||
|
--arg body "${release_body}" \
|
||||||
|
--arg target "${sha}" \
|
||||||
|
'{tag_name: $tag, name: $name, body: $body, draft: false, prerelease: false} +
|
||||||
|
(if $target == "" then {} else {target_commitish: $target} end)')"
|
||||||
|
|
||||||
|
response_file="$(mktemp)"
|
||||||
|
status="$(curl -sS -o "${response_file}" -w "%{http_code}" \
|
||||||
|
-X POST "${api_url}/repos/${repository}/releases" \
|
||||||
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data "${release_payload}")"
|
||||||
|
|
||||||
|
if [[ "${status}" == "201" ]]; then
|
||||||
|
release_id="$(jq -r '.id' "${response_file}")"
|
||||||
|
elif [[ "${status}" == "409" ]]; then
|
||||||
|
release_id="$(curl -fsS \
|
||||||
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||||
|
"${api_url}/repos/${repository}/releases?limit=100" |
|
||||||
|
jq -r --arg tag "${TAG_NAME}" '.[] | select(.tag_name == $tag) | .id' |
|
||||||
|
head -n 1)"
|
||||||
|
else
|
||||||
|
cat "${response_file}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "${release_id}" || "${release_id}" == "null" ]]; then
|
||||||
|
echo "Could not resolve Gitea release id for ${TAG_NAME}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
existing_asset_id="$(curl -fsS \
|
||||||
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||||
|
"${api_url}/repos/${repository}/releases/${release_id}/assets" |
|
||||||
|
jq -r --arg name "${IPA_NAME}" '.[] | select(.name == $name) | .id' |
|
||||||
|
head -n 1)"
|
||||||
|
|
||||||
|
if [[ -n "${existing_asset_id}" && "${existing_asset_id}" != "null" ]]; then
|
||||||
|
curl -fsS -X DELETE \
|
||||||
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||||
|
"${api_url}/repos/${repository}/releases/${release_id}/assets/${existing_asset_id}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
asset_name="$(jq -rn --arg value "${IPA_NAME}" '$value | @uri')"
|
||||||
|
curl -fsS -X POST \
|
||||||
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||||
|
-F "attachment=@${IPA_PATH}" \
|
||||||
|
"${api_url}/repos/${repository}/releases/${release_id}/assets?name=${asset_name}" >/dev/null
|
||||||
|
|
||||||
|
echo "Published ${IPA_NAME} to ${release_name}"
|
||||||
231
ios/Gemfile.lock
Normal file
231
ios/Gemfile.lock
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
CFPropertyList (3.0.9)
|
||||||
|
abbrev (0.1.2)
|
||||||
|
addressable (2.9.0)
|
||||||
|
public_suffix (>= 2.0.2, < 8.0)
|
||||||
|
artifactory (3.0.17)
|
||||||
|
atomos (0.1.3)
|
||||||
|
aws-eventstream (1.3.2)
|
||||||
|
aws-partitions (1.1109.0)
|
||||||
|
aws-sdk-core (3.224.1)
|
||||||
|
aws-eventstream (~> 1, >= 1.3.0)
|
||||||
|
aws-partitions (~> 1, >= 1.992.0)
|
||||||
|
aws-sigv4 (~> 1.9)
|
||||||
|
base64
|
||||||
|
jmespath (~> 1, >= 1.6.1)
|
||||||
|
logger
|
||||||
|
aws-sdk-kms (1.101.0)
|
||||||
|
aws-sdk-core (~> 3, >= 3.216.0)
|
||||||
|
aws-sigv4 (~> 1.5)
|
||||||
|
aws-sdk-s3 (1.188.0)
|
||||||
|
aws-sdk-core (~> 3, >= 3.224.1)
|
||||||
|
aws-sdk-kms (~> 1)
|
||||||
|
aws-sigv4 (~> 1.5)
|
||||||
|
aws-sigv4 (1.11.0)
|
||||||
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
|
babosa (1.0.4)
|
||||||
|
base64 (0.2.0)
|
||||||
|
claide (1.1.0)
|
||||||
|
colored (1.2)
|
||||||
|
colored2 (3.1.2)
|
||||||
|
commander (4.6.0)
|
||||||
|
highline (~> 2.0.0)
|
||||||
|
csv (3.3.5)
|
||||||
|
declarative (0.0.20)
|
||||||
|
digest-crc (0.7.0)
|
||||||
|
rake (>= 12.0.0, < 14.0.0)
|
||||||
|
domain_name (0.5.20190701)
|
||||||
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
|
dotenv (2.8.1)
|
||||||
|
emoji_regex (3.2.3)
|
||||||
|
excon (0.109.0)
|
||||||
|
faraday (1.10.6)
|
||||||
|
faraday-em_http (~> 1.0)
|
||||||
|
faraday-em_synchrony (~> 1.0)
|
||||||
|
faraday-excon (~> 1.1)
|
||||||
|
faraday-httpclient (~> 1.0)
|
||||||
|
faraday-multipart (~> 1.0)
|
||||||
|
faraday-net_http (~> 1.0)
|
||||||
|
faraday-net_http_persistent (~> 1.0)
|
||||||
|
faraday-patron (~> 1.0)
|
||||||
|
faraday-rack (~> 1.0)
|
||||||
|
faraday-retry (~> 1.0)
|
||||||
|
ruby2_keywords (>= 0.0.4)
|
||||||
|
faraday-cookie_jar (0.0.8)
|
||||||
|
faraday (>= 0.8.0)
|
||||||
|
http-cookie (>= 1.0.0)
|
||||||
|
faraday-em_http (1.0.0)
|
||||||
|
faraday-em_synchrony (1.0.1)
|
||||||
|
faraday-excon (1.1.0)
|
||||||
|
faraday-httpclient (1.0.1)
|
||||||
|
faraday-multipart (1.2.0)
|
||||||
|
multipart-post (~> 2.0)
|
||||||
|
faraday-net_http (1.0.2)
|
||||||
|
faraday-net_http_persistent (1.2.0)
|
||||||
|
faraday-patron (1.0.0)
|
||||||
|
faraday-rack (1.0.0)
|
||||||
|
faraday-retry (1.0.4)
|
||||||
|
faraday_middleware (1.2.1)
|
||||||
|
faraday (~> 1.0)
|
||||||
|
fastimage (2.4.1)
|
||||||
|
fastlane (2.230.0)
|
||||||
|
CFPropertyList (>= 2.3, < 4.0.0)
|
||||||
|
abbrev (~> 0.1.2)
|
||||||
|
addressable (>= 2.8, < 3.0.0)
|
||||||
|
artifactory (~> 3.0)
|
||||||
|
aws-sdk-s3 (~> 1.0)
|
||||||
|
babosa (>= 1.0.3, < 2.0.0)
|
||||||
|
base64 (~> 0.2.0)
|
||||||
|
bundler (>= 1.12.0, < 3.0.0)
|
||||||
|
colored (~> 1.2)
|
||||||
|
commander (~> 4.6)
|
||||||
|
csv (~> 3.3)
|
||||||
|
dotenv (>= 2.1.1, < 3.0.0)
|
||||||
|
emoji_regex (>= 0.1, < 4.0)
|
||||||
|
excon (>= 0.71.0, < 1.0.0)
|
||||||
|
faraday (~> 1.0)
|
||||||
|
faraday-cookie_jar (~> 0.0.6)
|
||||||
|
faraday_middleware (~> 1.0)
|
||||||
|
fastimage (>= 2.1.0, < 3.0.0)
|
||||||
|
fastlane-sirp (>= 1.0.0)
|
||||||
|
gh_inspector (>= 1.1.2, < 2.0.0)
|
||||||
|
google-apis-androidpublisher_v3 (~> 0.3)
|
||||||
|
google-apis-playcustomapp_v1 (~> 0.1)
|
||||||
|
google-cloud-env (>= 1.6.0, < 2.0.0)
|
||||||
|
google-cloud-storage (~> 1.31)
|
||||||
|
highline (~> 2.0)
|
||||||
|
http-cookie (~> 1.0.5)
|
||||||
|
json (< 3.0.0)
|
||||||
|
jwt (>= 2.1.0, < 3)
|
||||||
|
logger (>= 1.6, < 2.0)
|
||||||
|
mini_magick (>= 4.9.4, < 5.0.0)
|
||||||
|
multipart-post (>= 2.0.0, < 3.0.0)
|
||||||
|
mutex_m (~> 0.3.0)
|
||||||
|
naturally (~> 2.2)
|
||||||
|
nkf (~> 0.2.0)
|
||||||
|
optparse (>= 0.1.1, < 1.0.0)
|
||||||
|
plist (>= 3.1.0, < 4.0.0)
|
||||||
|
rubyzip (>= 2.0.0, < 3.0.0)
|
||||||
|
security (= 0.1.5)
|
||||||
|
simctl (~> 1.6.3)
|
||||||
|
terminal-notifier (>= 2.0.0, < 3.0.0)
|
||||||
|
terminal-table (~> 3)
|
||||||
|
tty-screen (>= 0.6.3, < 1.0.0)
|
||||||
|
tty-spinner (>= 0.8.0, < 1.0.0)
|
||||||
|
word_wrap (~> 1.0.0)
|
||||||
|
xcodeproj (>= 1.13.0, < 2.0.0)
|
||||||
|
xcpretty (~> 0.4.1)
|
||||||
|
xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
|
||||||
|
fastlane-sirp (1.1.0)
|
||||||
|
gh_inspector (1.1.3)
|
||||||
|
google-apis-androidpublisher_v3 (0.54.0)
|
||||||
|
google-apis-core (>= 0.11.0, < 2.a)
|
||||||
|
google-apis-core (0.11.3)
|
||||||
|
addressable (~> 2.5, >= 2.5.1)
|
||||||
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
|
httpclient (>= 2.8.1, < 3.a)
|
||||||
|
mini_mime (~> 1.0)
|
||||||
|
representable (~> 3.0)
|
||||||
|
retriable (>= 2.0, < 4.a)
|
||||||
|
rexml
|
||||||
|
google-apis-iamcredentials_v1 (0.17.0)
|
||||||
|
google-apis-core (>= 0.11.0, < 2.a)
|
||||||
|
google-apis-playcustomapp_v1 (0.13.0)
|
||||||
|
google-apis-core (>= 0.11.0, < 2.a)
|
||||||
|
google-apis-storage_v1 (0.29.0)
|
||||||
|
google-apis-core (>= 0.11.0, < 2.a)
|
||||||
|
google-cloud-core (1.6.1)
|
||||||
|
google-cloud-env (>= 1.0, < 3.a)
|
||||||
|
google-cloud-errors (~> 1.0)
|
||||||
|
google-cloud-env (1.6.0)
|
||||||
|
faraday (>= 0.17.3, < 3.0)
|
||||||
|
google-cloud-errors (1.3.1)
|
||||||
|
google-cloud-storage (1.45.0)
|
||||||
|
addressable (~> 2.8)
|
||||||
|
digest-crc (~> 0.4)
|
||||||
|
google-apis-iamcredentials_v1 (~> 0.1)
|
||||||
|
google-apis-storage_v1 (~> 0.29.0)
|
||||||
|
google-cloud-core (~> 1.6)
|
||||||
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
|
mini_mime (~> 1.0)
|
||||||
|
googleauth (1.8.1)
|
||||||
|
faraday (>= 0.17.3, < 3.a)
|
||||||
|
jwt (>= 1.4, < 3.0)
|
||||||
|
multi_json (~> 1.11)
|
||||||
|
os (>= 0.9, < 2.0)
|
||||||
|
signet (>= 0.16, < 2.a)
|
||||||
|
highline (2.0.3)
|
||||||
|
http-cookie (1.0.8)
|
||||||
|
domain_name (~> 0.5)
|
||||||
|
httpclient (2.9.0)
|
||||||
|
mutex_m
|
||||||
|
jmespath (1.6.2)
|
||||||
|
json (2.7.6)
|
||||||
|
jwt (2.10.3)
|
||||||
|
base64
|
||||||
|
logger (1.7.0)
|
||||||
|
mini_magick (4.13.2)
|
||||||
|
mini_mime (1.1.5)
|
||||||
|
multi_json (1.15.0)
|
||||||
|
multipart-post (2.4.1)
|
||||||
|
mutex_m (0.3.0)
|
||||||
|
nanaimo (0.4.0)
|
||||||
|
naturally (2.3.0)
|
||||||
|
nkf (0.2.0)
|
||||||
|
optparse (0.8.1)
|
||||||
|
os (1.1.4)
|
||||||
|
plist (3.7.2)
|
||||||
|
public_suffix (5.1.1)
|
||||||
|
rake (13.4.2)
|
||||||
|
representable (3.2.0)
|
||||||
|
declarative (< 0.1.0)
|
||||||
|
trailblazer-option (>= 0.1.1, < 0.2.0)
|
||||||
|
uber (< 0.2.0)
|
||||||
|
retriable (3.8.0)
|
||||||
|
rexml (3.4.4)
|
||||||
|
rouge (3.28.0)
|
||||||
|
ruby2_keywords (0.0.5)
|
||||||
|
rubyzip (2.4.1)
|
||||||
|
security (0.1.5)
|
||||||
|
signet (0.18.0)
|
||||||
|
addressable (~> 2.8)
|
||||||
|
faraday (>= 0.17.5, < 3.a)
|
||||||
|
jwt (>= 1.5, < 3.0)
|
||||||
|
multi_json (~> 1.10)
|
||||||
|
simctl (1.6.10)
|
||||||
|
CFPropertyList
|
||||||
|
naturally
|
||||||
|
terminal-notifier (2.0.0)
|
||||||
|
terminal-table (3.0.2)
|
||||||
|
unicode-display_width (>= 1.1.1, < 3)
|
||||||
|
trailblazer-option (0.1.2)
|
||||||
|
tty-cursor (0.7.1)
|
||||||
|
tty-screen (0.8.2)
|
||||||
|
tty-spinner (0.9.3)
|
||||||
|
tty-cursor (~> 0.7)
|
||||||
|
uber (0.1.0)
|
||||||
|
unf (0.2.0)
|
||||||
|
unicode-display_width (2.6.0)
|
||||||
|
word_wrap (1.0.0)
|
||||||
|
xcodeproj (1.27.0)
|
||||||
|
CFPropertyList (>= 2.3.3, < 4.0)
|
||||||
|
atomos (~> 0.1.3)
|
||||||
|
claide (>= 1.0.2, < 2.0)
|
||||||
|
colored2 (~> 3.1)
|
||||||
|
nanaimo (~> 0.4.0)
|
||||||
|
rexml (>= 3.3.6, < 4.0)
|
||||||
|
xcpretty (0.4.1)
|
||||||
|
rouge (~> 3.28.0)
|
||||||
|
xcpretty-travis-formatter (1.0.1)
|
||||||
|
xcpretty (~> 0.2, >= 0.0.7)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
ruby
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
fastlane (~> 2.227)
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.5.23
|
||||||
32
ios/fastlane/CI.md
Normal file
32
ios/fastlane/CI.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# TestFlight Release CI
|
||||||
|
|
||||||
|
Gitea Actions publishes iOS releases from tags that match:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
release/vN.N.N
|
||||||
|
```
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git tag release/v1.10.0
|
||||||
|
git push origin release/v1.10.0
|
||||||
|
```
|
||||||
|
|
||||||
|
The release job runs on the `xcode` runner label, imports the signing p12 with
|
||||||
|
`Apple-Actions/import-codesign-certs`, builds and uploads the app with fastlane,
|
||||||
|
then creates or updates the matching Gitea release with the generated IPA as an
|
||||||
|
asset.
|
||||||
|
|
||||||
|
Required repository secrets:
|
||||||
|
|
||||||
|
```text
|
||||||
|
APPSTORE_CERTIFICATES_FILE_BASE64
|
||||||
|
APPSTORE_CERTIFICATES_PASSWORD
|
||||||
|
FASTLANE_USER
|
||||||
|
FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
The workflow uses Gitea's built-in `GITEA_TOKEN` for release creation and asset
|
||||||
|
upload, with `contents: write` permissions. In Gitea this covers release asset
|
||||||
|
publication.
|
||||||
@@ -42,9 +42,9 @@ def local_build_number
|
|||||||
end
|
end
|
||||||
|
|
||||||
def normalize_version_tag(tag)
|
def normalize_version_tag(tag)
|
||||||
version = tag.to_s.strip.sub(/\Av/, "")
|
version = tag.to_s.strip.sub(%r{\Arelease/}, "").sub(/\Av/, "")
|
||||||
unless version.match?(/\A\d+\.\d+(\.\d+)?\z/)
|
unless version.match?(/\A\d+\.\d+\.\d+\z/)
|
||||||
UI.user_error!("Release tag #{tag.inspect} must look like v1.10 or v1.10.0")
|
UI.user_error!("Release tag #{tag.inspect} must look like release/v1.10.0")
|
||||||
end
|
end
|
||||||
version
|
version
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user