1
1
name : Publish gem
2
2
3
3
# TODO: Implement a dry-run mode to verify the checks without publishing
4
- on : workflow_dispatch # yamllint disable-line rule:truthy
4
+ on : # yamllint disable-line rule:truthy
5
+ workflow_dispatch :
6
+ inputs :
7
+ force :
8
+ description : ' Force release bypassing verification checks'
9
+ type : boolean
10
+ default : false
11
+ required : false
5
12
6
13
concurrency : " rubygems" # Only one publish job at a time
7
14
14
21
runs-on : ubuntu-24.04
15
22
permissions :
16
23
checks : read
24
+ contents : read
17
25
outputs :
18
26
version : ${{ steps.version.outputs.version }}
19
27
steps :
29
37
30
38
# Check if the gem version is already published
31
39
- name : Verify gem version
40
+ if : ${{ !inputs.force }}
32
41
env :
33
42
GEM_VERSION : ${{ steps.version.outputs.version }}
34
43
run : |
@@ -39,12 +48,67 @@ jobs:
39
48
echo "Version $GEM_VERSION is not published yet"
40
49
fi
41
50
42
- # TODO: Verify draft release
43
- # TODO: Verify milestone
51
+ # Check if there is a draft release for this version
52
+ # API: https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#list-releases
53
+ - name : Verify draft release
54
+ if : ${{ !inputs.force }}
55
+ continue-on-error : true # TODO: Remove when figuring out why draft release are not returned from API
56
+ env :
57
+ GEM_VERSION : ${{ steps.version.outputs.version }}
58
+ uses : actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
59
+ with :
60
+ script : |
61
+ const { data: releases } = await github.rest.repos.listReleases({
62
+ owner: context.repo.owner,
63
+ repo: context.repo.repo,
64
+ });
65
+
66
+ console.log(releases);
67
+
68
+ const versionTag = `v${process.env.GEM_VERSION}`;
69
+ const draftRelease = releases.find(
70
+ release => release.tag_name === versionTag && release.draft === true
71
+ );
72
+
73
+ if (!draftRelease) {
74
+ core.setFailed(`No draft release found with tag ${versionTag}. Please create a draft release first.`);
75
+ return;
76
+ }
77
+
78
+ console.log(`Found draft release with tag ${versionTag} (ID: ${draftRelease.id})`);
79
+
80
+ # Check if there is an open milestone for this version
81
+ # API: https://docs.github.com/en/rest/issues/milestones?apiVersion=2022-11-28#list-milestones
82
+ - name : Verify milestone
83
+ if : ${{ !inputs.force }}
84
+ env :
85
+ GEM_VERSION : ${{ steps.version.outputs.version }}
86
+ uses : actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
87
+ with :
88
+ script : |
89
+ const { data: milestones } = await github.rest.issues.listMilestones({
90
+ owner: context.repo.owner,
91
+ repo: context.repo.repo,
92
+ state: 'open'
93
+ });
94
+
95
+ console.log(milestones);
96
+
97
+ const versionMilestone = milestones.find(
98
+ milestone => milestone.title === process.env.GEM_VERSION
99
+ );
100
+
101
+ if (!versionMilestone) {
102
+ core.setFailed(`No open milestone found with title ${process.env.GEM_VERSION}. Please create a milestone first.`);
103
+ return;
104
+ }
105
+
106
+ console.log(`Found open milestone ${process.env.GEM_VERSION} (ID: ${versionMilestone.number})`);
44
107
45
108
# Check if the commit has passed all Github checks
46
109
# API: https://docs.github.com/en/rest/checks/runs?apiVersion=2022-11-28#list-check-runs-for-a-git-reference
47
110
- name : Verify check runs
111
+ if : ${{ !inputs.force }}
48
112
uses : actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
49
113
with :
50
114
script : |
69
133
# Check if the commit has passed external CI checks
70
134
# API: https://docs.github.com/en/rest/commits/statuses?apiVersion=2022-11-28#get-the-combined-status-for-a-specific-reference
71
135
- name : Verify commit status
136
+ if : ${{ !inputs.force }}
72
137
uses : actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
73
138
with :
74
139
script : |
84
149
85
150
# Check if the commit has all the checks passed
86
151
- name : Verify deferred commit data
152
+ if : ${{ !inputs.force }}
87
153
# NOTE:
88
154
#
89
155
# This step uses Github's internal API (for rendering the status of the checks in UI),
@@ -100,7 +166,10 @@ jobs:
100
166
echo "::error::Status check state is '$STATUS'. See: $COMMIT_URL"
101
167
exit 1
102
168
fi
103
-
169
+ - name : Warning for bypassing checks
170
+ if : ${{ inputs.force }}
171
+ run : |
172
+ echo "::warning::Bypassing verification checks"
104
173
105
174
rubygems-release :
106
175
name : Build and push gem to RubyGems.org
0 commit comments