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
92 changes: 92 additions & 0 deletions .github/workflows/publish-gem.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Publish gem

on:
workflow_dispatch:
inputs:
tag:
description: Existing release tag to publish or retry (for example v13.1.1)
required: true
type: string

permissions:
contents: read

concurrency:
group: publish-gem-${{ inputs.tag }}
cancel-in-progress: false

env:
RELEASE_TAG: ${{ inputs.tag }}

jobs:
verify:
if: github.repository == 'appium/ruby_console'
runs-on: ubuntu-latest
outputs:
gem_filename: ${{ steps.artifact.outputs.gem-filename }}
steps:
- name: Validate tag syntax
shell: bash
run: |
if [[ ! "$RELEASE_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z]+([.-][0-9A-Za-z]+)*)?$ ]]; then
echo 'Expected a release tag such as v13.1.1 or v13.2.0-rc.1' >&2
exit 1
fi
- uses: actions/checkout@v7
with:
ref: refs/tags/${{ env.RELEASE_TAG }}
fetch-depth: 0
persist-credentials: false
- name: Verify release commit belongs to master
run: git merge-base --is-ancestor HEAD origin/master
- uses: ruby/setup-ruby@v1
with:
ruby-version: '4.0'
bundler-cache: true
# Build before tools/tests can generate or update local files.
- name: Build gem from the tagged checkout
run: bundle exec rake build
- name: Run checks on the release commit
run: |
bundle exec rake rubocop
bundle exec ruby -Ilib bin/arc version
- name: Validate the built gem
id: package
uses: appium/appium-workflows/.github/actions/ruby-release-validate@b9358466aa945baa7afa4d8f177d9fa4f4515bc0
with:
gem-name: appium_console
version-file: lib/appium_console/version.rb
tag: ${{ env.RELEASE_TAG }}
- name: Record artifact filename for the publishing job
id: artifact
env:
VERIFIED_GEM_PATH: ${{ steps.package.outputs.gem-path }}
run: echo "gem-filename=$(basename "$VERIFIED_GEM_PATH")" >> "$GITHUB_OUTPUT"
- uses: actions/upload-artifact@v4
with:
name: release-gem
path: ${{ steps.package.outputs.gem-path }}
if-no-files-found: error
retention-days: 14

publish:
needs: verify
runs-on: ubuntu-latest
environment: rubygems
permissions:
contents: read
id-token: write
steps:
- uses: ruby/setup-ruby@v1
with:
ruby-version: '4.0'
- uses: actions/download-artifact@v4
with:
name: release-gem
path: pkg
- name: Authenticate with RubyGems Trusted Publishing
uses: rubygems/configure-rubygems-credentials@daab0479595bcc124493903b3df17273d86e073f
- name: Publish the verified gem
env:
GEM_PATH_TO_PUBLISH: pkg/${{ needs.verify.outputs.gem_filename }}
run: gem push --host https://rubygems.org "$GEM_PATH_TO_PUBLISH"
55 changes: 55 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Release Please

on:
push:
branches: [master]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: release-please
cancel-in-progress: false

jobs:
release:
if: github.repository == 'appium/ruby_console'
permissions:
contents: write
pull-requests: write
issues: write
actions: write
runs-on: ubuntu-latest
env:
TZ: UTC
steps:
- name: Update release PR or create GitHub Release
id: release
uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
target-branch: master
config-file: release-please-config.json
manifest-file: .release-please-manifest.json

# GITHUB_TOKEN does not automatically start downstream workflows.
# Explicit dispatch runs checks on the release PR commit without a bot key.
- name: Run release PR checks
if: steps.release.outputs.prs_created == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
RELEASE_PR: ${{ steps.release.outputs.pr }}
run: |
branch=$(jq -er '.headBranchName | select(type == "string" and length > 0)' <<< "$RELEASE_PR")
for workflow in release-validation.yml; do
gh workflow run "$workflow" --ref "$branch"
done
- name: Publish the new release
if: steps.release.outputs.release_created == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
RELEASE_TAG: ${{ steps.release.outputs.tag_name }}
run: gh workflow run publish-gem.yml --ref master -f "tag=$RELEASE_TAG"
33 changes: 33 additions & 0 deletions .github/workflows/release-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Release validation

on:
workflow_dispatch:
pull_request:
push:
branches: [master]

permissions:
contents: read

jobs:
package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: ruby/setup-ruby@v1
with:
ruby-version: '4.0'
bundler-cache: true
- name: Check console
run: |
bundle exec rake rubocop
bundle exec ruby -Ilib bin/arc version
- name: Build gem
run: bundle exec rake build
- name: Validate built gem
uses: appium/appium-workflows/.github/actions/ruby-release-validate@b9358466aa945baa7afa4d8f177d9fa4f4515bc0
with:
gem-name: appium_console
version-file: lib/appium_console/version.rb
3 changes: 3 additions & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
".": "4.2.0"
}
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
AllCops:
TargetRubyVersion: 3.1
Metrics/LineLength:
Layout/LineLength:
Max: 128
Metrics/MethodLength:
Enabled: false
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Changelog

Historical commit-level notes through 4.2.0 are in [release_notes.md](release_notes.md).
New entries are maintained by Release Please.

## [4.2.0] - 2025-01-25

- See the historical release notes for this release.
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
source 'https://rubygems.org'
gemspec

gem 'appium_thor', '~> 2.0'
gem 'rake', '~> 13.0'
gem 'rubocop', '1.90.0'
167 changes: 167 additions & 0 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# Releasing appium_console

Release Please prepares the release PR, version, changelog, tag, and GitHub Release.
GitHub Actions builds and tests the tagged code, then publishes that exact gem to
RubyGems.org using Trusted Publishing. `appium_thor` is no longer required.

After the one-time setup, the maintainer's normal release action is to review and
merge the release PR. There is no local version bump, tag push, or gem push.

## One-time setup

1. In repository **Settings → Actions → General → Workflow permissions**, enable
**Allow GitHub Actions to create and approve pull requests** (the organization
policy must permit it). Workflows declare their own permissions. Release Please
uses the built-in `GITHUB_TOKEN`; no GitHub App, PAT, or new GitHub secret is needed.
2. Keep the normal branch protection/rulesets on `master`. Require the `package` job from **Release validation** before merging
a release PR. Do not exempt the release bot from those merge checks. Its direct
writes are to the generated release PR branch and release tags, not master.
3. Create the GitHub Actions environment `rubygems`. Permit release tags (`v*`) and
the `master` branch (for automated publishing and retries). Add a required reviewer only if a
separate approval for each publication is wanted; otherwise merging the release
PR is the normal human decision.
4. As an owner of `appium_console` on RubyGems.org, configure a Trusted Publisher:
- Repository owner: `appium`
- Repository name: `ruby_console`
- Workflow filename: `publish-gem.yml`
- Environment: `rubygems`
5. Merge the migration after its CI passes. A push to master or a manual run of
**Release Please** updates the pending release PR. Configure the RubyGems
publisher before merging that first release PR.

This follows the standard `GITHUB_TOKEN` and OIDC authentication used by Appium's
Python client and XCUITest driver release workflows. Release Please explicitly
uses `workflow_dispatch` to run the package validation
workflow on the release PR branch, and **Publish gem** on master with the new tag.
These events run with `GITHUB_TOKEN` without a separate bot credential. All workflow
files must first be on master for dispatch to work.

GitHub may also show approval-required `pull_request` runs for bot-created PRs.
The dispatched package checks do not require that approval. If additional
PR-event-only checks are made required, adapt their triggers as well.

No credentials, remote settings, tags, or releases are created by installing these
files. Configure the RubyGems publisher before merging the first release PR.

## Normal release

1. Merge ordinary changes using Conventional Commit titles/messages. A `fix:`
produces a patch bump, `feat:` a minor bump, and a breaking-change marker such as
`feat!:` a major bump. Chore-only changes do not normally create a release PR.
2. Release Please maintains a PR updating `lib/appium_console/version.rb`,
`.release-please-manifest.json`, and `CHANGELOG.md`. Its standard `x-release-please-date` annotation also updates
`Appium::Console::DATE` in the same PR. Wait for checks on the final PR commit.
3. Review the version and release notes, then merge the PR when ready. If master
has advanced, require current checks before merging through the repository rules.
4. Release Please creates `v<version>` and a GitHub Release, then dispatches
**Publish gem** with that tag. **Publish gem** verifies
that the tag is on master's history, builds the gem before test tools can modify local files, runs checks, and verifies
the tag, source version, manifest, changelog date, and packaged gem identity.
5. Only a successful verification job uploads a gem for the separate publishing
job. That job has the OIDC permission, downloads the verified artifact, and uses
`gem push`. It does not rebuild the package or create another tag.

A GitHub Release can exist before RubyGems publication succeeds. The **Publish gem**
workflow result is the publication status; creating a GitHub Release alone does
not mean the gem has been published.

`release_notes.md` is retained as historical commit-level notes through 4.2.0.
New release notes are generated in `CHANGELOG.md` and GitHub Releases. `DATE` is the
release-preparation date recorded in that changelog, not the later RubyGems upload
timestamp. No public version/date constant is removed.

## Choosing a version or publishing an RC

For a one-off explicit version, use Release Please's `Release-As: 13.2.0` footer in
a commit included in the release, or the `release-as` package setting. If using the
setting, remove it after the release so it does not keep forcing the same version.
Review the generated PR instead of changing only VERSION independently of the
manifest and changelog.

For an RC, configure the root package with `"prerelease": true` and an explicit
`"release-as": "13.2.0-rc.1"`. Release Please uses a SemVer tag such as
`v13.2.0-rc.1`; RubyGems normalizes the gem version/filename to `13.2.0.pre.rc.1`.
The release validator accepts that mapping. Use `rc.2`, etc. for further RCs.
Before the stable release, remove the prerelease flag and explicit RC version (or
set the intended stable release version explicitly). The default configuration
is for stable releases from master, not a parallel prerelease branch.

## Recovery

- **Release PR has a date mismatch:** rerun **Release Please**. Alternatively, check
out its branch, use the shared validator’s `prepare-date` command described
below, and commit the date change. Do not edit the date to the upload day independently of the changelog.
- **PR checks do not start:** inspect the **Run release PR checks** step, Actions
policy, and workflow permissions. Each dispatched workflow must exist on master.
Retry the affected workflow from the generated PR branch using **Run workflow**;
rerunning Release Please may not return an unchanged PR in its outputs.
- **Tag/Release exists but publication failed:** correct external setup if needed
and rerun the failed workflow jobs. If dispatch itself failed, run
**Publish gem** from master with the existing tag; rerunning Release Please does
not necessarily emit an already-created release again. The verified artifact is kept for 14 days.
If it has expired, run **Publish gem** manually from master with the same existing
release tag; it rechecks and rebuilds that tag. This retry route is for releases
containing this publishing workflow, not older historical tags.
- **RubyGems already has that version:** confirm the existing release before retrying.
The workflow deliberately does not treat every push failure as success. Published
versions cannot be overwritten. Do not move the tag or rebuild different source
under the same version; use a new release when a code fix is needed.
- **A build or validation needs a source-code fix:** fix master and prepare a new
release. The retry path always checks out the original tag, so it cannot silently
publish newer master code under that tag.

## Local checks without publication

```sh
bundle install
bundle exec rake rubocop
bundle exec ruby -Ilib bin/arc version
bundle exec rake build
```

The CI workflows use the shared [ruby-release-validate Action](https://github.com/appium/appium-workflows/tree/b9358466aa945baa7afa4d8f177d9fa4f4515bc0/.github/actions/ruby-release-validate),
pinned to commit `b9358466aa945baa7afa4d8f177d9fa4f4515bc0`. Its validation tests are maintained
in that repository; this repository keeps its own application tests.

For local metadata/package verification, clone the shared repository alongside
this checkout, then run the same validator (adjust paths as needed):

```sh
git clone https://github.com/appium/appium-workflows.git ../appium-workflows
git -C ../appium-workflows checkout b9358466aa945baa7afa4d8f177d9fa4f4515bc0
ruby ../appium-workflows/.github/actions/ruby-release-validate/release.rb \
verify --root . --gem-name appium_console --version-file lib/appium_console/version.rb
```

Add `--tag v<version>` to verify a prospective tag. For date recovery, replace
`verify` with `prepare-date` and omit `--tag`; it copies the changelog date into
the local version file. Neither command pushes or publishes. If the shared
checkout already exists, use it instead of cloning again.

The Action returns an absolute `gem-path` for artifact upload. The workflow passes
only the filename to the separate publishing job, which downloads the artifact
into its own `pkg/` directory. The publishing workflow, `rubygems` environment,
and Trusted Publisher registration remain in this repository.

The repository bootstrap is pinned to the existing `v4.2.0` commit
`2f63a20264d375195d49b975df974522605c54ce`, with manifest version `4.2.0`. This avoids
replaying all historical changes on the first release. Once Release Please has
made its first release, its bootstrap setting is ignored and can be removed.

## References

- [Release Please](https://github.com/googleapis/release-please)
- [GitHub workflow triggering and token behavior](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/trigger-a-workflow)
- [Appium Python client release workflow](https://github.com/appium/python-client/blob/master/.github/workflows/publish.yml)
- [Appium XCUITest driver release workflow](https://github.com/appium/appium-xcuitest-driver/blob/master/.github/workflows/publish.js.yml)
- [Manifest and prerelease configuration](https://github.com/googleapis/release-please/blob/main/docs/manifest-releaser.md)
- [RubyGems Trusted Publishing](https://guides.rubygems.org/trusted-publishing/)
- [RubyGems credentials Action](https://github.com/rubygems/configure-rubygems-credentials)

The credentials Action is used instead of `rubygems/release-gem` because Release
Please already owns the tag. Authentication plus `gem push` avoids invoking a
second tool's tag-creation/release sequence.

The runtime `thor` dependency is retained for the `arc` CLI. Only the separate
`appium_thor` release tooling is removed. The old `thor spec` task referred to a
nonexistent `spec/` directory; release helper tests now live in the shared Action repository.
20 changes: 0 additions & 20 deletions Thorfile

This file was deleted.

Loading