Skip to content

Commit 399af87

Browse files
Merge pull request #6 from fac/devp/v2
Version v2 - Change: Don't pass the gem host around as an environment variable, extract from the gemspec. - Change: Don't pass gem keys around in environment variables anymore. Use the installed creds by key name. - Add: input key to set the key name in gem credentials to use. - Change: Release/pre-release inputs collapsed into single pre-release input. Push is either release or pre-release version, can't do both (or none!) in the same call anymore. - Add: Add linter for action code. - Change: tag-release input renamed to just tag. - Change: Use command line args instead of env variables for the internal command.
2 parents 3571ffe + c112604 commit 399af87

File tree

6 files changed

+132
-83
lines changed

6 files changed

+132
-83
lines changed

.github/workflows/linter.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Lint Code Base
2+
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
3+
4+
on:
5+
pull_request:
6+
push:
7+
branches:
8+
- main
9+
10+
jobs:
11+
linter:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v2
15+
with:
16+
ref: ${{ github.head_ref }}
17+
fetch-depth: 0 # Full history to get a proper list of changed files within `super-linter`
18+
19+
- name: Lint Code Base
20+
uses: github/super-linter@v3
21+
env:
22+
VALIDATE_ALL_CODEBASE: false
23+
VALIDATE_BASH: true
24+
VALIDATE_YAML: true
25+
DEFAULT_BRANCH: main
26+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
# CHANGELOG
22

3+
TODO: v2 changes
4+
35
## [Unreleased]
6+
7+
## [2.0.0] - 2021-04-26
8+
9+
- Change: Don't pass the gem host around as an environment variable, extract from the gemspec.
10+
- Change: Don't pass gem keys around in environment variables anymore. Use the installed creds by key name.
11+
- Add: input `key` to set the key name in gem credentials to use.
12+
- Change: Release/pre-release inputs collapsed into single pre-release input. Push is either release or pre-release version, can't do both (or none!) in the same call anymore.
13+
- Add: Add linter for action code.
14+
- Change: `tag-release` input renamed to just `tag`.
15+
- Change: Use command line args instead of env variables for the internal command.
16+
417
## [1.3.0] - 2021-04-16
518

619
- Fix: clean shell log handling for `gem push` call

README.md

Lines changed: 31 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
## Description
44

5-
Action to push gems to a gem cutter compatible repository. Probably RubyGems or GitHub Packages. It expects the authentication to have already been setup, using the environment variables GEM_HOST and GEM_HOST_API_KEY. See [fac/ruby-gem-setup-github-packages-action](https://github.com/fac/ruby-gem-setup-github-packages-action) for an action to set this up for you to push to GitHub.
5+
Action to push gems to a gem cutter compatible repository. Basically RubyGems or GitHub Packages. It expects the authentication to have already been setup, `~/.gem/credentials` contains a token for the repo and you know the name of the key.
6+
See [fac/ruby-gem-setup-github-packages-action](https://github.com/fac/ruby-gem-setup-github-packages-action) for an action to set this up for you. It is actually pretty easy if pushing to the same repo.
67

78
If the gem version already exists in the repo the action will no-op and still set a success status. This makes it easier to integrate into workflows, safe to re-run (intentionally or accidentally) and wont push duplicate/replacement packages.
9+
It will still raise an error visible in the summary, letting you know the version already exists.
810

911
## Usage
1012

@@ -16,38 +18,28 @@ Build and push all new version of the gem:
1618

1719
```yaml
1820
steps:
19-
# Setup ruby environment
2021
- uses: actions/checkout@v2
2122
- uses: ruby/setup-ruby@v1 # .ruby-version
2223
with:
23-
bundler-cache: true # bundle install and cache
24+
bundler-cache: true # bundle install
25+
- run: bundle exec rake build
2426

25-
- name: Build Gem
26-
shell: bash
27-
run: bundle exec rake build
28-
29-
- name: Setup GPR
30-
uses: fac/ruby-gem-setup-github-packages-action@v1
27+
- uses: fac/ruby-gem-setup-github-packages-action@v2
3128
with:
3229
token: ${{ secrets.github_token }}
3330

34-
- name: Push Gem
35-
uses: fac/ruby-gem-push-action@v1
31+
- uses: fac/ruby-gem-push-action@v2
32+
with:
33+
key: github
3634
```
3735
38-
If you want to use a different gem host or key:
39-
40-
```yaml
41-
- name: Push Gem
42-
uses: fac/ruby-gem-push-action@v1
43-
env:
44-
gem_host: http://gems.example.com
45-
gem_host_api_key: ${{ secrets.EXAMPLE_API_KEY }}
46-
```
36+
Note that the ruby-gem-push-action will push to the host given in the gemspec. The token needs to match. Trying to push to a different host will fail.
4737
4838
### Separate release and pre-release workflow
4939
50-
You probably don't want to push all versions from any branch. More likely you would want to push release versions from your default branch (e.g. main) and pre-release from PR builds. To help with this the release and pre-release inputs can be used:
40+
By default, the action only acts on non-pre-release versions, and prints a message if it thinks the gem has a pre-release version number. If you set the input option `pre-release: true`, then it will only act on pre-release versions, and will skip over regular versions. That way, you can have 2 calls to the action, using the workflow to decide the logic.
41+
42+
Say you want to push release versions from your default branch (main) and pre-release versions from PR builds:
5143

5244
```yaml
5345
name: Gem Build and Release
@@ -69,32 +61,32 @@ jobs:
6961
7062
release:
7163
name: Gem / Release
72-
needs: test
64+
needs: test # Only release IF the tests pass
7365
runs-on: ubuntu-latest
7466
7567
steps:
7668
- uses: actions/checkout@v2
7769
- uses: ruby/setup-ruby@v1
70+
- run: bundle exec rake build
7871
79-
- name: Build Gem
80-
run: bundle exec rake build
81-
82-
- name: Setup GPR
83-
uses: fac/ruby-gem-setup-github-packages-action@v1
72+
# Setup repo auth
73+
- uses: fac/ruby-gem-setup-github-packages-action@v2
8474
with:
8575
token: ${{ secrets.github_token }}
8676
8777
# Release production gem version from default branch
88-
- name: Push Release Gem
78+
- name: Release Gem
8979
if: github.ref == 'refs/heads/main'
90-
uses: fac/ruby-gem-push-action@v1
80+
uses: fac/ruby-gem-push-action@v2
81+
with:
82+
key: github
9183
9284
# PR branch builds will release pre-release gems
93-
- name: Push Pre-Release Gem
85+
- name: Pre-Release Gem
9486
if: github.ref != 'refs/heads/main'
95-
uses: fac/ruby-gem-push-action@v1
87+
uses: fac/ruby-gem-push-action@v2
9688
with:
97-
release: false
89+
key: github
9890
pre-release: true
9991
```
10092

@@ -103,31 +95,26 @@ The release job runs if the tests pass, we always package the gem to test that w
10395

10496
## Inputs
10597

106-
### package-glob
98+
### gem-glob
10799

108100
File glob to match the gem file to push. The default `pkg/*.gem` picks up gems built using `bundle exec rake build`. You may need to set this if your your gem builds another way.
109101

110102
```yaml
111103
- name: Push Gem
112104
uses: fac/ruby-gem-push-action@v1
113105
with:
114-
package-glob: build/special.gem
106+
gem-glob: build/special.gem
115107
```
116-
117-
### release
118-
119-
Whether to push new release versions of the gem. Defaults to true.
120-
121108
### pre-release
122109

123-
Whether to push new pre-release versions of the gem. Defaults to true.
110+
Whether to push new pre-release versions of the gem and ignore releases, instead of the normal, push prod releases but ignore pre-release.
124111

125-
### tag-release
112+
### tag
126113

127114
When true (the default), after pushing a new gem version tag the repo with
128115
the version number prefixed with `v`. e.g. after pushing version `0.1.0`, the
129-
tag will be `v0.1.0`. This is the same behavior as `gem tag`, but internally
130-
implemented to work with older gem versions.
116+
tag will be `v0.1.0`. This is the same behavior as `gem tag`. (Internally
117+
implemented to work with older gem versions and around bugs that caused tags for failed pushes, which then blocked re-pushing.
131118

132119
The tag commit and push will be made as the author of the commit being tagged.
133120

@@ -139,14 +126,7 @@ If we pushed a gem to the repository, this will be set to the version pushed.
139126

140127
## Environment Variables
141128

142-
### GEM_HOST_API_KEY
143-
144-
Read to get the API key string (prefixed token with Bearer), to access the package repo. Used by `gem push`.
145-
146-
### GEM_HOST
147-
148-
The host URL for pushing gems to.
149-
129+
None.
150130
## Authors
151131

152132
* FreeAgent <opensource@freeagent.com>

action.yml

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ name: Gem Push
33
author: FreeAgent
44
description: Push gem packages to a rubygems compatible repository
55
inputs:
6-
package-glob:
6+
key:
7+
description: "Name of credentials key to use from ~/.gem/credentials."
8+
default: ""
9+
gem-glob:
710
description: File glob to match the .gem files to push
811
default: "pkg/*.gem"
9-
release:
10-
description: Whether to push release versions
11-
default: true
1212
pre-release:
13-
description: Whether to push pre-release versions
14-
default: true
15-
tag-release:
13+
description: Whether to push pre-release versions, instead of release versions (the default).
14+
default: false
15+
tag:
1616
description: After pushing a new gem version, git tag with the version string
1717
default: true
1818
outputs:
@@ -26,12 +26,8 @@ runs:
2626
- name: Push Gem
2727
id: push-gem
2828
shell: bash
29-
env:
30-
# Expects GEM_HOST and GEM_HOST_API_KEY to be set
31-
INPUT_PACKAGE_GLOB: ${{ inputs.package-glob }}
32-
INPUT_RELEASE: ${{ inputs.release }}
33-
INPUT_PRE_RELEASE: ${{ inputs.pre-release }}
34-
INPUT_TAG_RELEASE: ${{ inputs.tag-release }}
3529
run: |
3630
PATH="${{ github.action_path }}:$PATH"
37-
gem-push-action
31+
args=""
32+
[ '${{ inputs.tag }}' == true ] && args="$args -t"
33+
gem-push-action -k "${{inputs.key}}" $args ${{inputs.gem-glob}}

gem-push-action

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,55 @@
1-
#!/usr/bin/bash
1+
#!/usr/bin/env bash
22
set -e -o pipefail
33

4-
if parse-gemspec --is-pre-release; then
5-
if [[ $INPUT_PRE_RELEASE != true ]]; then
4+
KEY=""
5+
PRE_RELEASE=false
6+
TAG_RELEASE=false
7+
8+
usage() {
9+
echo "Usage: $0 [-k KEY] [-p] GEMFILE"
10+
echo
11+
echo Options:
12+
echo " GEMFILE The pre-built .gem pkg you want to push"
13+
echo " -k KEY Set the gem host credentials key name. Default: '$KEY'"
14+
echo " -p Do a pre-release, ignore otherwise. Default: $PRE_RELEASE"
15+
echo " -t After pushing a new version, git tag the current ref. Default: $TAG_RELEASE"
16+
echo " -h Show this help"
17+
exit 0
18+
}
19+
20+
while getopts ":hk:pt" opt; do
21+
case ${opt} in
22+
h ) usage
23+
;;
24+
k ) KEY=$OPTARG
25+
;;
26+
p ) PRE_RELEASE=true
27+
;;
28+
t ) TAG_RELEASE=true
29+
;;
30+
\? ) usage
31+
;;
32+
esac
33+
done
34+
shift $((OPTIND -1))
35+
36+
GEM_FILE="$1"
37+
38+
# By default read the gem host from the gemspec, if they dont match the push
39+
# will fail! Allow override if GEM_HOST is already exported.
40+
push_host="$(parse-gemspec --push-host)"
41+
GEM_HOST="${GEM_HOST:-$push_host}"
42+
43+
if parse-gemspec --is-pre-release && [[ $PRE_RELEASE != true ]];
44+
then
645
echo "Ignoring pre-release. To release, pass pre-release: true as an input"
746
exit 0
8-
fi
9-
elif [[ $INPUT_RELEASE != true ]]; then
10-
echo "Ignoring release. To release, pass release: true as an input"
11-
exit 0
1247
fi
1348

1449
# Capture as we can't tell why gem push failed from the exit code and it logs
1550
# everything to stdout, so need to grep the output. Gem existing is ok, other
1651
# errors not. Avoids playing games setting up auth differently for gem query.
17-
# Note: the glob is intentially unquoted, we want a glob!
18-
if ! gem push --host "$GEM_HOST" $INPUT_PACKAGE_GLOB >push.out; then
52+
if ! gem push --key="$KEY" --host "$GEM_HOST" "$GEM_FILE" >push.out; then
1953
gemerr=$?
2054
sed 's/^Error:/::error::/' push.out
2155
if grep -q "has already been pushed" push.out; then
@@ -26,7 +60,7 @@ fi
2660

2761
echo "::set-output name=pushed-version::$( parse-gemspec --version )"
2862

29-
if [[ $INPUT_TAG_RELEASE == true ]]; then
63+
if [[ $TAG_RELEASE == true ]]; then
3064
tagname="v$( parse-gemspec --version )"
3165
git config user.name "$(git log -1 --pretty=format:%an)"
3266
git config user.email "$(git log -1 --pretty=format:%ae)"

parse-gemspec

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ end
2424

2525
OptionParser.new do |opts|
2626
opts.banner = "Usage: #{File.basename($0)} [options]"
27-
opts.on("-h", "--help", "Prints this help") do
28-
puts! opts
29-
end
30-
opts.on("--name", "Output gemspec name") do |v|
31-
puts! spec.name
32-
end
33-
opts.on("--version", "Output gemspec gem version") do |v|
34-
puts! spec.version
27+
opts.on("-h", "--help", "Prints this help") do puts! opts end
28+
29+
opts.on("--name", "Output name") do |v| puts! spec.name end
30+
opts.on("--version", "Output gem version") do |v| puts! spec.version end
31+
opts.on("--metadata", "Output metadata") do |v| puts! spec.metadata end
32+
opts.on("--push-host", "Output metadata.allowed_push_host") do |v|
33+
puts! spec.metadata.dig "allowed_push_host"
3534
end
35+
3636
opts.on("--is-pre-release", "Exit 0 if pre-release, 1 otherwise") do |v|
3737
exit 0 if spec.version.prerelease?
3838
exit 1

0 commit comments

Comments
 (0)