Skip to content

Commit 0fda80b

Browse files
authored
Merge pull request #37 from ConvertAPI/ci/trunk-based-release
Trunk-based release pipeline; 3.0.1
2 parents 551d77e + 3c4901f commit 0fda80b

14 files changed

Lines changed: 544 additions & 55 deletions

File tree

‎.github/dependabot.yml‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
version: 2
2+
updates:
3+
# The workflows pin every action to a commit SHA; Dependabot keeps those pins current.
4+
- package-ecosystem: github-actions
5+
directory: /
6+
schedule:
7+
interval: weekly
8+
groups:
9+
actions:
10+
patterns: ['*']

‎.github/workflows/build.yml‎

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
name: Build
2+
run-name: >-
3+
${{ github.event_name == 'pull_request' && format('Checking that #{0} builds', github.event.pull_request.number)
4+
|| format('Building {0}', github.ref_name) }}
5+
6+
# Trunk-based: main is the only long-lived branch. Every pull request and every push to main runs the specs
7+
# on each supported Ruby and builds the gem, but nothing is published here: RubyGems versions are permanent,
8+
# so a release is a deliberate act - publishing a GitHub Release v{semver}, which runs publish.yml. The
9+
# required status check is the `build` job, which passes only when every Ruby passed and the gem built.
10+
on:
11+
pull_request:
12+
branches: [main]
13+
push:
14+
branches: [main]
15+
workflow_dispatch:
16+
17+
permissions:
18+
contents: read
19+
20+
concurrency:
21+
# A newer push to the same pull request cancels the older build; builds of main never cancel each other.
22+
group: build-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || github.run_id }}
23+
cancel-in-progress: true
24+
25+
jobs:
26+
test:
27+
name: test (Ruby ${{ matrix.ruby }})
28+
runs-on: ubuntu-latest
29+
timeout-minutes: 15
30+
strategy:
31+
fail-fast: false
32+
matrix:
33+
ruby: ['3.2', '3.3', '3.4', '4.0']
34+
steps:
35+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
36+
with:
37+
persist-credentials: false
38+
39+
- uses: ruby/setup-ruby@824c0e29fdfc7d689c191c27acc969d2d04b7dd8 # v1.331.0
40+
with:
41+
ruby-version: ${{ matrix.ruby }}
42+
bundler-cache: true
43+
44+
# The examples tagged `live: true` convert real files on ConvertAPI and run only when the
45+
# CONVERTAPI_SECRET secret (an API token) exists; pull requests from forks and Dependabot never get it,
46+
# so for them only the offline examples run. CONVERTAPI_BASE_URI (a variable) can point them at
47+
# another deployment, e.g. https://stag-v2.convertapi.com/.
48+
- name: Specs
49+
env:
50+
CONVERT_API_SECRET: ${{ secrets.CONVERTAPI_SECRET }}
51+
CONVERT_API_BASE_URI: ${{ vars.CONVERTAPI_BASE_URI }}
52+
RUBYOPT: -W
53+
run: bundle exec rake spec
54+
55+
build:
56+
name: build
57+
needs: test
58+
# Runs even when a test job failed, so that the required check reports a failure instead of being
59+
# skipped - a skipped required check counts as passed.
60+
if: always()
61+
runs-on: ubuntu-latest
62+
timeout-minutes: 10
63+
steps:
64+
- name: Check the specs
65+
env:
66+
RESULT: ${{ needs.test.result }}
67+
run: |
68+
if [ "$RESULT" != success ]; then
69+
echo "::error::The specs did not pass on every Ruby ($RESULT)"
70+
exit 1
71+
fi
72+
73+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
74+
with:
75+
fetch-depth: 0
76+
persist-credentials: false
77+
78+
- uses: ruby/setup-ruby@824c0e29fdfc7d689c191c27acc969d2d04b7dd8 # v1.331.0
79+
with:
80+
ruby-version: '3.4'
81+
82+
# ConvertApi::VERSION is the gem's version and goes into the User-Agent of every request; publish.yml
83+
# refuses a tag that does not match it. It may run ahead of the latest release, never behind it.
84+
- name: Check the version
85+
id: version
86+
run: |
87+
set -euo pipefail
88+
VERSION=$(ruby -Ilib -rconvert_api/version -e 'print ConvertApi::VERSION')
89+
if ! [[ "$VERSION" =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(\.(alpha|beta|rc)\.(0|[1-9][0-9]*))?$ ]]; then
90+
echo "::error file=lib/convert_api/version.rb::ConvertApi::VERSION '$VERSION' is not {major}.{minor}.{patch} or {major}.{minor}.{patch}.{alpha|beta|rc}.{n}"
91+
exit 1
92+
fi
93+
# The highest release so far, pre-releases included (v3.1.0-rc.2 is gem version 3.1.0.rc.2). Gem::Version
94+
# sorts a pre-release below its release, so this also refuses a pre-release of a released version.
95+
LATEST=$(git tag --list 'v*' | ruby -e '
96+
tags = $stdin.read.split.grep(/\Av\d+\.\d+\.\d+(-(alpha|beta|rc)\.\d+)?\z/)
97+
print tags.map { |t| Gem::Version.new(t.delete_prefix("v").tr("-", ".")) }.max')
98+
if [ -n "$LATEST" ] && ! ruby -e 'exit Gem::Version.new(ARGV[0]) >= Gem::Version.new(ARGV[1])' "$VERSION" "$LATEST"; then
99+
echo "::error file=lib/convert_api/version.rb::ConvertApi::VERSION $VERSION is lower than the latest release $LATEST"
100+
exit 1
101+
fi
102+
{
103+
echo "version=$VERSION"
104+
echo "latest=$LATEST"
105+
} >> "$GITHUB_OUTPUT"
106+
107+
# The gem a release would publish, built and installed outside the checkout, so a change can be tried
108+
# out from the run's artifact before it is released.
109+
- name: Build the gem
110+
env:
111+
VERSION: ${{ steps.version.outputs.version }}
112+
run: |
113+
set -euo pipefail
114+
mkdir -p dist
115+
gem build convert_api.gemspec --output "dist/convert_api-$VERSION.gem"
116+
GEM_HOME="$RUNNER_TEMP/gems" gem install --local --no-document "dist/convert_api-$VERSION.gem"
117+
cd "$RUNNER_TEMP"
118+
GEM_HOME="$RUNNER_TEMP/gems" GEM_PATH="$RUNNER_TEMP/gems" ruby -W -e '
119+
require "convert_api"
120+
abort "loaded #{ConvertApi::VERSION}, expected #{ARGV[0]}" unless ConvertApi::VERSION == ARGV[0]
121+
abort "loaded from #{$LOADED_FEATURES.grep(/convert_api\.rb\z/)}" unless $LOADED_FEATURES.grep(/convert_api\.rb\z/).all? { |f| f.start_with?(ENV["GEM_HOME"]) }
122+
puts ConvertApi::Client::USER_AGENT' "$VERSION"
123+
124+
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
125+
with:
126+
name: convert_api-${{ steps.version.outputs.version }}-run${{ github.run_number }}
127+
path: dist/
128+
retention-days: 14
129+
if-no-files-found: error
130+
131+
- name: Summary
132+
env:
133+
VERSION: ${{ steps.version.outputs.version }}
134+
LATEST: ${{ steps.version.outputs.latest }}
135+
run: |
136+
{
137+
echo "| | |"
138+
echo "|---|---|"
139+
echo "| \`ConvertApi::VERSION\` | \`$VERSION\` (latest release: \`$LATEST\`) |"
140+
echo "| Gem | \`convert_api-$VERSION.gem\` (artifact only, not published) |"
141+
echo "| Ruby | 3.2, 3.3, 3.4, 4.0 |"
142+
} >> "$GITHUB_STEP_SUMMARY"

‎.github/workflows/main.yml‎

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)