inquirex-tools 0.8.0 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.env.encrypted +11 -0
- data/.env.example +5 -0
- data/.envrc +1 -0
- data/.relaxed_rubocop.yml +153 -0
- data/.sops.yaml +6 -0
- data/.sopsy.sha +1 -0
- data/.sopsy.yml +11 -0
- data/exe/inquirex +3 -2
- data/exe/inquirexor +1 -0
- data/justfile +158 -0
- data/lib/inquirex/tools/commands/changelogs.rb +5 -3
- data/lib/inquirex/tools/commands/publish.rb +36 -0
- data/lib/inquirex/tools/commands/versions_bump.rb +34 -0
- data/lib/inquirex/tools/commands/versions_check.rb +36 -0
- data/lib/inquirex/tools/commands.rb +7 -3
- data/lib/inquirex/tools/publisher.rb +160 -0
- data/lib/inquirex/tools/version.rb +1 -1
- data/lib/inquirex/tools/version_bumper.rb +169 -0
- data/lib/inquirex/tools/version_checker.rb +110 -0
- data/lib/inquirex/tools/workspace.rb +30 -27
- data/lib/inquirex/tools.rb +10 -5
- metadata +31 -3
- data/lib/inquirex/tools/commands/versions.rb +0 -41
- data/lib/inquirex/tools/versions.rb +0 -125
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a86b68b3b9abc13c3046754f8b5f43a69f84360e3b581e5760ab9145049da76a
|
|
4
|
+
data.tar.gz: 5001830e113f7c7b63547f9f49ca10cb290b946c90a0916313e83dee0e1f479a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ab2d90315649ab9d2465156964f6436b96a79a5fb0a32c4489ef2910d8a991166da17bcd1731bae08d830097bb2249b91ca9c7ad339e171d48004b812363c8f7
|
|
7
|
+
data.tar.gz: f7258bdb64b70a46a21b09ccb0f58111077e326b290fdaa3fc72e5cfea1c661abe546e005bce892ec69662fed81c938cbf1645a9cad4eb8e61f0061b56ff721f
|
data/.env.encrypted
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#ENC[AES256_GCM,data:4mpgKeRs3A2HXmt/FjaIn561sybb9L9oX7gVygSpct//wHWjT5I+lT3Vf5UlMGTv42RKAAL5CgF+SRr4bni33A6CeU3ODQ3vYAo=,iv:oP7xJ9m3C0ezlTznZ1NkqCvu52MLHpDnTkmc7Q0lhhY=,tag:7SoYBTYtcIex2jgqECrAuA==,type:comment]
|
|
2
|
+
#ENC[AES256_GCM,data:89N9zu88zeviY33xeiZOFaLTDxv51jf8SmuZ07NVzAOUDdQAPkKuYkqvOOZpYXjYTDJVY16yYLMYGSmVq8f5rbmWDYC/gJn31m0=,iv:01XkrGj3H6uf6tIdHZxSEpJ/a8LVpo/TidFgRHTJUXo=,tag:lTMSW/QgGaWub1pZrre9TA==,type:comment]
|
|
3
|
+
#ENC[AES256_GCM,data:nYuulT9DlDl+zOPlhK0IqJSahj1KiunqenUbfzPllxxEvJNqMUKU/kVaK73YbaDSUPdAeRXbFH3trz8CQ4uBR5yjQCnv12DD9VVjXw==,iv:7hWr2ajKbKA7lPqtBsmvUycJTF69PVcHUk1kA0T6kXo=,tag:2fnWYnft/u2hVkadn5dsdw==,type:comment]
|
|
4
|
+
#ENC[AES256_GCM,data:kDDhc1ZMB8McDQ2dcEnvT24UWRUq/WNKJ/QuhFpO54K6P0IXFUbmBoqIK2X408HPcJLz9etlw7NAZt1AaQ==,iv:+BRUu6mSooyQt+bazHq/dgXVISTjEfiIJTyUR0N9XgI=,tag:pU6kCwETMJ4neWSHLDBX9g==,type:comment]
|
|
5
|
+
OP_ACCOUNT=ENC[AES256_GCM,data:QLsZSJQqdNSFAIqVDBVHh4kO9TrP9Hm4CZA=,iv:qlqTEsjHfV5AowWnsgWYjU2udMgFmXsYF3GK1PIjzsw=,tag:PUivzRC+pPufSY5P+HG9Rg==,type:str]
|
|
6
|
+
sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHBpdi1wMjU2IER3YUVVQSBBMHphcXd3\nNmtHWjkxVDdwZDZON213c3hmeEpGbW9GSmszM2ZWUGxxRWoyQwpReTZ3bzZFeEJM\nWlF0VVFTNGVnaFlmMVRSUmtoVEZKOCtVRlU1VjYya25FCi0tLSBJTEtJcTducjM4\nSndWNmZub1hiMCsxMTFwbkpSTXVtZnNKemt6UGpzS1BRCptxoolSJ98Ngajq1/pI\nWo0FMY9hEPh5m1m0lBcWBRqbnr23APyywtt89b0UOKhRHhf9KMw6zTfk+KQC3wj0\nNug=\n-----END AGE ENCRYPTED FILE-----\n
|
|
7
|
+
sops_age__list_0__map_recipient=age1se1qd8tpc9v42uuqz974uxx84mdz0aejujrzssmyjl6fvmwgx3gm62wjjxjyws
|
|
8
|
+
sops_lastmodified=2026-08-06T01:38:07Z
|
|
9
|
+
sops_mac=ENC[AES256_GCM,data:4J6BN+p3cXmbGMOfmjXtkPDvRI1jlflrEObvC30TwwrbBXhBW+WLSUOiGM8aVC+pSCzCNykpjkKw47ElMA8jD927xMg1BaglWTtbFPaqVgCVXXnM0c1XL6+oWa80QULZGXViG4W7c4JTYxzqsvhGEpKx0CUFO43GKibx/BaUgAo=,iv:+F76/yNF/kctS0844U7IS9RUyMIg4fkltqlbS+l9mrQ=,tag:rwtNHQpXnEuDLl77qMesZw==,type:str]
|
|
10
|
+
sops_unencrypted_suffix=_unencrypted
|
|
11
|
+
sops_version=3.13.2
|
data/.env.example
ADDED
data/.envrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
PATH_add bin
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Relaxed.Ruby.Style
|
|
2
|
+
## Version 2.5
|
|
3
|
+
|
|
4
|
+
Style/Alias:
|
|
5
|
+
Enabled: false
|
|
6
|
+
StyleGuide: https://relaxed.ruby.style/#stylealias
|
|
7
|
+
|
|
8
|
+
Style/AsciiComments:
|
|
9
|
+
Enabled: false
|
|
10
|
+
StyleGuide: https://relaxed.ruby.style/#styleasciicomments
|
|
11
|
+
|
|
12
|
+
Style/BeginBlock:
|
|
13
|
+
Enabled: false
|
|
14
|
+
StyleGuide: https://relaxed.ruby.style/#stylebeginblock
|
|
15
|
+
|
|
16
|
+
Style/BlockDelimiters:
|
|
17
|
+
Enabled: false
|
|
18
|
+
StyleGuide: https://relaxed.ruby.style/#styleblockdelimiters
|
|
19
|
+
|
|
20
|
+
Style/CommentAnnotation:
|
|
21
|
+
Enabled: false
|
|
22
|
+
StyleGuide: https://relaxed.ruby.style/#stylecommentannotation
|
|
23
|
+
|
|
24
|
+
Style/Documentation:
|
|
25
|
+
Enabled: false
|
|
26
|
+
StyleGuide: https://relaxed.ruby.style/#styledocumentation
|
|
27
|
+
|
|
28
|
+
Layout/DotPosition:
|
|
29
|
+
Enabled: false
|
|
30
|
+
StyleGuide: https://relaxed.ruby.style/#layoutdotposition
|
|
31
|
+
|
|
32
|
+
Style/DoubleNegation:
|
|
33
|
+
Enabled: false
|
|
34
|
+
StyleGuide: https://relaxed.ruby.style/#styledoublenegation
|
|
35
|
+
|
|
36
|
+
Style/EndBlock:
|
|
37
|
+
Enabled: false
|
|
38
|
+
StyleGuide: https://relaxed.ruby.style/#styleendblock
|
|
39
|
+
|
|
40
|
+
Style/FormatString:
|
|
41
|
+
Enabled: false
|
|
42
|
+
StyleGuide: https://relaxed.ruby.style/#styleformatstring
|
|
43
|
+
|
|
44
|
+
Style/IfUnlessModifier:
|
|
45
|
+
Enabled: false
|
|
46
|
+
StyleGuide: https://relaxed.ruby.style/#styleifunlessmodifier
|
|
47
|
+
|
|
48
|
+
Style/Lambda:
|
|
49
|
+
Enabled: false
|
|
50
|
+
StyleGuide: https://relaxed.ruby.style/#stylelambda
|
|
51
|
+
|
|
52
|
+
Style/ModuleFunction:
|
|
53
|
+
Enabled: false
|
|
54
|
+
StyleGuide: https://relaxed.ruby.style/#stylemodulefunction
|
|
55
|
+
|
|
56
|
+
Style/MultilineBlockChain:
|
|
57
|
+
Enabled: false
|
|
58
|
+
StyleGuide: https://relaxed.ruby.style/#stylemultilineblockchain
|
|
59
|
+
|
|
60
|
+
Style/NegatedIf:
|
|
61
|
+
Enabled: false
|
|
62
|
+
StyleGuide: https://relaxed.ruby.style/#stylenegatedif
|
|
63
|
+
|
|
64
|
+
Style/NegatedWhile:
|
|
65
|
+
Enabled: false
|
|
66
|
+
StyleGuide: https://relaxed.ruby.style/#stylenegatedwhile
|
|
67
|
+
|
|
68
|
+
Style/NumericPredicate:
|
|
69
|
+
Enabled: false
|
|
70
|
+
StyleGuide: https://relaxed.ruby.style/#stylenumericpredicate
|
|
71
|
+
|
|
72
|
+
Style/ParallelAssignment:
|
|
73
|
+
Enabled: false
|
|
74
|
+
StyleGuide: https://relaxed.ruby.style/#styleparallelassignment
|
|
75
|
+
|
|
76
|
+
Style/PercentLiteralDelimiters:
|
|
77
|
+
Enabled: false
|
|
78
|
+
StyleGuide: https://relaxed.ruby.style/#stylepercentliteraldelimiters
|
|
79
|
+
|
|
80
|
+
Style/PerlBackrefs:
|
|
81
|
+
Enabled: false
|
|
82
|
+
StyleGuide: https://relaxed.ruby.style/#styleperlbackrefs
|
|
83
|
+
|
|
84
|
+
Style/Semicolon:
|
|
85
|
+
Enabled: false
|
|
86
|
+
StyleGuide: https://relaxed.ruby.style/#stylesemicolon
|
|
87
|
+
|
|
88
|
+
Style/SignalException:
|
|
89
|
+
Enabled: false
|
|
90
|
+
StyleGuide: https://relaxed.ruby.style/#stylesignalexception
|
|
91
|
+
|
|
92
|
+
Style/SingleLineBlockParams:
|
|
93
|
+
Enabled: false
|
|
94
|
+
StyleGuide: https://relaxed.ruby.style/#stylesinglelineblockparams
|
|
95
|
+
|
|
96
|
+
Style/SingleLineMethods:
|
|
97
|
+
Enabled: false
|
|
98
|
+
StyleGuide: https://relaxed.ruby.style/#stylesinglelinemethods
|
|
99
|
+
|
|
100
|
+
Layout/SpaceBeforeBlockBraces:
|
|
101
|
+
Enabled: false
|
|
102
|
+
StyleGuide: https://relaxed.ruby.style/#layoutspacebeforeblockbraces
|
|
103
|
+
|
|
104
|
+
Layout/SpaceInsideParens:
|
|
105
|
+
Enabled: false
|
|
106
|
+
StyleGuide: https://relaxed.ruby.style/#layoutspaceinsideparens
|
|
107
|
+
|
|
108
|
+
Style/SpecialGlobalVars:
|
|
109
|
+
Enabled: false
|
|
110
|
+
StyleGuide: https://relaxed.ruby.style/#stylespecialglobalvars
|
|
111
|
+
|
|
112
|
+
Style/StringLiterals:
|
|
113
|
+
Enabled: false
|
|
114
|
+
StyleGuide: https://relaxed.ruby.style/#stylestringliterals
|
|
115
|
+
|
|
116
|
+
Style/TrailingCommaInArguments:
|
|
117
|
+
Enabled: false
|
|
118
|
+
StyleGuide: https://relaxed.ruby.style/#styletrailingcommainarguments
|
|
119
|
+
|
|
120
|
+
Style/TrailingCommaInArrayLiteral:
|
|
121
|
+
Enabled: false
|
|
122
|
+
StyleGuide: https://relaxed.ruby.style/#styletrailingcommainarrayliteral
|
|
123
|
+
|
|
124
|
+
Style/TrailingCommaInHashLiteral:
|
|
125
|
+
Enabled: false
|
|
126
|
+
StyleGuide: https://relaxed.ruby.style/#styletrailingcommainhashliteral
|
|
127
|
+
|
|
128
|
+
Style/SymbolArray:
|
|
129
|
+
Enabled: false
|
|
130
|
+
StyleGuide: http://relaxed.ruby.style/#stylesymbolarray
|
|
131
|
+
|
|
132
|
+
Style/WhileUntilModifier:
|
|
133
|
+
Enabled: false
|
|
134
|
+
StyleGuide: https://relaxed.ruby.style/#stylewhileuntilmodifier
|
|
135
|
+
|
|
136
|
+
Style/WordArray:
|
|
137
|
+
Enabled: false
|
|
138
|
+
StyleGuide: https://relaxed.ruby.style/#stylewordarray
|
|
139
|
+
|
|
140
|
+
Lint/AmbiguousRegexpLiteral:
|
|
141
|
+
Enabled: false
|
|
142
|
+
StyleGuide: https://relaxed.ruby.style/#lintambiguousregexpliteral
|
|
143
|
+
|
|
144
|
+
Lint/AssignmentInCondition:
|
|
145
|
+
Enabled: false
|
|
146
|
+
StyleGuide: https://relaxed.ruby.style/#lintassignmentincondition
|
|
147
|
+
|
|
148
|
+
Layout/LineLength:
|
|
149
|
+
Enabled: false
|
|
150
|
+
|
|
151
|
+
Metrics:
|
|
152
|
+
Enabled: false
|
|
153
|
+
|
data/.sops.yaml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Managed by sopsy. Maps encrypted files to their age recipients.
|
|
2
|
+
creation_rules:
|
|
3
|
+
- path_regex: '\.env\.encrypted$'
|
|
4
|
+
age: 'age1se1qd8tpc9v42uuqz974uxx84mdz0aejujrzssmyjl6fvmwgx3gm62wjjxjyws'
|
|
5
|
+
- path_regex: '\.encrypted$'
|
|
6
|
+
age: 'age1se1qd8tpc9v42uuqz974uxx84mdz0aejujrzssmyjl6fvmwgx3gm62wjjxjyws'
|
data/.sopsy.sha
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
b95fff7b1445f7690843e41678e2676916ec792390828e5755e7ec554812aece
|
data/.sopsy.yml
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
recipients:
|
|
2
|
+
- name: admin
|
|
3
|
+
public_key: age1se1qd8tpc9v42uuqz974uxx84mdz0aejujrzssmyjl6fvmwgx3gm62wjjxjyws
|
|
4
|
+
username: kig
|
|
5
|
+
break_glass: false
|
|
6
|
+
encrypted_globs:
|
|
7
|
+
- '*.encrypted'
|
|
8
|
+
- .env.encrypted
|
|
9
|
+
- config/*.encrypted.yaml
|
|
10
|
+
sops_version: 3.13.2
|
|
11
|
+
join_request_ttl: 72h
|
data/exe/inquirex
CHANGED
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
# binary; this gem owns the bare name so cross-family tooling has one entry
|
|
6
6
|
# point and no two gems install a binary called `inquirex`.
|
|
7
7
|
#
|
|
8
|
-
# inquirex versions
|
|
9
|
-
# inquirex versions --
|
|
8
|
+
# inquirex versions-check # lockstep parity across the family
|
|
9
|
+
# inquirex versions-check --preflight # parity plus git release readiness
|
|
10
|
+
# inquirex versions-bump 0.8.0 # move every lockstep package
|
|
10
11
|
# inquirex changelogs
|
|
11
12
|
#
|
|
12
13
|
# Inside a checkout, prefer the repo's own Gemfile over whatever rubygems has
|
data/exe/inquirexor
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
inquirex
|
data/justfile
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# Tell 'just' to run bash, source our setup script, then execute the recipe
|
|
2
|
+
set shell := ["bash", "-c"]
|
|
3
|
+
|
|
4
|
+
version := `grep VERSION lib/inquirex/tools/version.rb | awk '{print $3}' | tr -d '"' | tr -d '\n'`
|
|
5
|
+
rbenv := 'eval "$(rbenv init - bash)"; bundle exec '
|
|
6
|
+
repo := 'git@github.com:inquirex/inquirex-tools.git'
|
|
7
|
+
|
|
8
|
+
# 1Password secret reference for the RubyGems TOTP, and the full path to `op`
|
|
9
|
+
# because a recipe does not inherit an interactive shell's PATH.
|
|
10
|
+
# The account is NOT named here: it is a private 1Password address and this
|
|
11
|
+
# file is public. `op` reads it from OP_ACCOUNT, exported by the ecosystem
|
|
12
|
+
# root's .envrc, which lives outside every repo. Two accounts are
|
|
13
|
+
# registered and only one holds the open-source-repos vault, so without
|
|
14
|
+
# OP_ACCOUNT the read can resolve against the wrong one, return nothing,
|
|
15
|
+
# and publish silently falls back to prompting mid-release.
|
|
16
|
+
op := '/opt/homebrew/bin/op'
|
|
17
|
+
otp_ref := 'op://open-source-repos/ruby-gems/one-time password?attribute=otp'
|
|
18
|
+
|
|
19
|
+
gem_name := 'inquirex-tools'
|
|
20
|
+
gem_file := 'pkg/' + gem_name + '-' + version + '.gem'
|
|
21
|
+
gem_url := 'https://rubygems.org/gems/' + gem_name
|
|
22
|
+
|
|
23
|
+
[no-exit-message]
|
|
24
|
+
recipes:
|
|
25
|
+
just --choose
|
|
26
|
+
|
|
27
|
+
# Sync all dependencies
|
|
28
|
+
install:
|
|
29
|
+
bin/setup
|
|
30
|
+
|
|
31
|
+
build: install
|
|
32
|
+
|
|
33
|
+
# Lint and reformat files
|
|
34
|
+
lint:
|
|
35
|
+
{{ rbenv }} rubocop
|
|
36
|
+
|
|
37
|
+
# Lint and reformat files (-a) — pass -A as an argument
|
|
38
|
+
format *args:
|
|
39
|
+
{{ rbenv }} rubocop -a {{ args }}
|
|
40
|
+
/usr/bin/find . -name '*.md' -exec mdformat --wrap no {} \; -print
|
|
41
|
+
|
|
42
|
+
# Run all the tests
|
|
43
|
+
test *args:
|
|
44
|
+
export ENVIRONMENT=test; {{ rbenv }} rspec {{args}}
|
|
45
|
+
|
|
46
|
+
# Run tests with coverage
|
|
47
|
+
test-coverage *args:
|
|
48
|
+
export ENVIRONMENT=test; export COVERAGE=true; {{ rbenv }} rspec {{ args }}
|
|
49
|
+
|
|
50
|
+
ci: lint test-coverage
|
|
51
|
+
|
|
52
|
+
alias check-all := ci
|
|
53
|
+
|
|
54
|
+
clean:
|
|
55
|
+
#!/usr/bin/env bash
|
|
56
|
+
@find . -name .DS_Store -delete -print || true
|
|
57
|
+
@rm -rf tmp/*
|
|
58
|
+
|
|
59
|
+
# Run all lefthook pre-commit hooks
|
|
60
|
+
lefthook:
|
|
61
|
+
{{ rbenv }} lefthook run pre-commit --all-files
|
|
62
|
+
|
|
63
|
+
# Print current gem version
|
|
64
|
+
version:
|
|
65
|
+
@echo "{{ version }}"
|
|
66
|
+
|
|
67
|
+
# Clobber
|
|
68
|
+
clobber:
|
|
69
|
+
{{ rbenv }} rake clobber
|
|
70
|
+
|
|
71
|
+
# Generate documentation
|
|
72
|
+
doc:
|
|
73
|
+
#!/usr/bin/env bash
|
|
74
|
+
{{ rbenv }} rake doc
|
|
75
|
+
|
|
76
|
+
# `gem push` rather than `rake release`: release also guards the tree, tags and
|
|
77
|
+
# pushes git — which `just release` does deliberately and separately — and it
|
|
78
|
+
# gives no way to pass a 2FA code, so it always stopped to prompt.
|
|
79
|
+
#
|
|
80
|
+
# The code comes from 1Password unless one is passed in:
|
|
81
|
+
#
|
|
82
|
+
# just publish # read the code from 1Password
|
|
83
|
+
# just publish 123456 # use this code
|
|
84
|
+
#
|
|
85
|
+
# `just publish-all` in inquirex-tools passes one, because a TOTP is single-use:
|
|
86
|
+
# four gems reading the same 30-second window would have the second push
|
|
87
|
+
# rejected as a replay.
|
|
88
|
+
#
|
|
89
|
+
# Build the .gem and push it to RubyGems, non-interactively
|
|
90
|
+
publish otp="": build
|
|
91
|
+
#!/usr/bin/env bash
|
|
92
|
+
set -euo pipefail
|
|
93
|
+
eval "$(rbenv init - bash 2>/dev/null || true)"
|
|
94
|
+
|
|
95
|
+
mkdir -p pkg
|
|
96
|
+
gem build {{ gem_name }}.gemspec --output "{{ gem_file }}"
|
|
97
|
+
|
|
98
|
+
# `|| true` is load-bearing: under `set -e` a failed `op read` — not signed
|
|
99
|
+
# in to 1Password, item renamed, op not installed — would abort the recipe
|
|
100
|
+
# before the prompting fallback below could run.
|
|
101
|
+
otp="{{ otp }}"
|
|
102
|
+
[[ -n "${otp}" ]] || otp=$({{ op }} read "{{ otp_ref }}" 2>/dev/null || true)
|
|
103
|
+
|
|
104
|
+
if [[ -n "${otp}" ]]; then
|
|
105
|
+
gem push "{{ gem_file }}" --otp "${otp}"
|
|
106
|
+
else
|
|
107
|
+
echo "rubygems: no OTP available — gem push will prompt if 2FA is required."
|
|
108
|
+
gem push "{{ gem_file }}"
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
# Only reachable when the push succeeded: `set -e` aborts the recipe on a
|
|
112
|
+
# non-zero `gem push`, so the page never opens for a release that failed.
|
|
113
|
+
echo "published {{ gem_name }} {{ version }} → {{ gem_url }}"
|
|
114
|
+
open "{{ gem_url }}" 2>/dev/null || xdg-open "{{ gem_url }}" 2>/dev/null || true
|
|
115
|
+
|
|
116
|
+
# Publish every package in the family, gems and npm packages alike.
|
|
117
|
+
#
|
|
118
|
+
# A thin wrapper: the ordering, the per-gem 2FA code and the stop-on-failure
|
|
119
|
+
# rule all live in Inquirex::Tools::Publisher, where they are unit-tested. This
|
|
120
|
+
# recipe only supplies the environment — OP_ACCOUNT, decrypted from
|
|
121
|
+
# .env.encrypted — that the Ruby side cannot obtain for itself.
|
|
122
|
+
#
|
|
123
|
+
# Only this repo carries the sopsy setup. Each package's `just publish` runs as
|
|
124
|
+
# a grandchild process and inherits the exported value, so the other five repos
|
|
125
|
+
# stay free of an encrypted env and a Touch ID prompt they do not need.
|
|
126
|
+
#
|
|
127
|
+
# just publish-all # publish for real
|
|
128
|
+
# just publish-all --dry-run # print the commands, run nothing
|
|
129
|
+
#
|
|
130
|
+
# Publish every package in the family (--dry-run to preview)
|
|
131
|
+
publish-all *args:
|
|
132
|
+
#!/usr/bin/env bash
|
|
133
|
+
set -euo pipefail
|
|
134
|
+
eval "$(rbenv init - bash 2>/dev/null || true)"
|
|
135
|
+
|
|
136
|
+
# `|| true`: a missing key, a locked Secure Enclave or no sopsy at all must
|
|
137
|
+
# not abort a release. Without OP_ACCOUNT the run still works — `op` falls
|
|
138
|
+
# back to the default account, and failing that, prompts.
|
|
139
|
+
if [[ -f .env.encrypted ]]; then
|
|
140
|
+
if secrets=$(sopsy decrypt .env.encrypted 2>/dev/null); then
|
|
141
|
+
set -a
|
|
142
|
+
eval "$(printf '%s\n' "${secrets}" | sed -E '/^#/d; /^$/d')"
|
|
143
|
+
set +a
|
|
144
|
+
echo "sopsy: OP_ACCOUNT=${OP_ACCOUNT:-<unset>}"
|
|
145
|
+
else
|
|
146
|
+
echo "sopsy: could not decrypt .env.encrypted — continuing without OP_ACCOUNT" >&2
|
|
147
|
+
fi
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
bundle exec exe/inquirex publish {{ args }}
|
|
151
|
+
|
|
152
|
+
# Tag v{{ version }}, publish the GH release, & refresh the Homebrew tap.
|
|
153
|
+
release:
|
|
154
|
+
git fetch --tags
|
|
155
|
+
git tag -f "v{{ version }}"
|
|
156
|
+
git push -f --tags
|
|
157
|
+
gh release delete -y "v{{ version }}" --repo {{ repo }} 2>/dev/null || true
|
|
158
|
+
gh release create "v{{ version }}" --generate-notes --repo {{ repo }}
|
|
@@ -7,12 +7,14 @@ module Inquirex
|
|
|
7
7
|
class Changelogs < Dry::CLI::Command
|
|
8
8
|
desc "Regenerate CHANGELOG.md from merged PRs"
|
|
9
9
|
|
|
10
|
-
argument :repos,
|
|
11
|
-
|
|
10
|
+
argument :repos,
|
|
11
|
+
type: :array,
|
|
12
|
+
required: false,
|
|
13
|
+
desc: "Repositories to regenerate (default: all configured)"
|
|
12
14
|
|
|
13
15
|
example [
|
|
14
16
|
" # every repo with a .github_changelog_generator",
|
|
15
|
-
"inquirex-
|
|
17
|
+
"inquirex-widget # just one"
|
|
16
18
|
]
|
|
17
19
|
|
|
18
20
|
# The GitHub token comes from `gh auth token`, so no secret is stored
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Inquirex
|
|
4
|
+
module Tools
|
|
5
|
+
module Commands
|
|
6
|
+
# `inquirex publish` — publishes every package in the family.
|
|
7
|
+
#
|
|
8
|
+
# The orchestrator runs each package's own `just publish` in that
|
|
9
|
+
# package's directory, so how a package reaches its registry stays that
|
|
10
|
+
# package's business. What this adds is the order, a fresh 2FA code per
|
|
11
|
+
# gem, and stopping at the first failure.
|
|
12
|
+
class Publish < Dry::CLI::Command
|
|
13
|
+
desc "Publish every package in the family to RubyGems and npm"
|
|
14
|
+
|
|
15
|
+
option :dry_run,
|
|
16
|
+
type: :boolean,
|
|
17
|
+
default: false,
|
|
18
|
+
desc: "Print the commands that would run; publish nothing"
|
|
19
|
+
|
|
20
|
+
example [
|
|
21
|
+
" # publish the whole family",
|
|
22
|
+
"--dry-run # print what would happen, touch no registry"
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
# @param options [Hash] parsed CLI options
|
|
26
|
+
# @return [void]
|
|
27
|
+
def call(**options)
|
|
28
|
+
exit(1) unless Inquirex::Tools::Publisher.new.call(dry_run: options.fetch(:dry_run, false))
|
|
29
|
+
rescue Inquirex::Tools::Error => e
|
|
30
|
+
warn "ERROR: #{e.message}"
|
|
31
|
+
exit 1
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Inquirex
|
|
4
|
+
module Tools
|
|
5
|
+
module Commands
|
|
6
|
+
# `inquirex versions-bump` — moves every lockstep package to one version.
|
|
7
|
+
#
|
|
8
|
+
# The write counterpart of `inquirex versions-check`. Separate commands
|
|
9
|
+
# rather than one command with a `--set` flag, so nothing that writes can
|
|
10
|
+
# be reached by accident from a command meant to report.
|
|
11
|
+
class VersionsBump < Dry::CLI::Command
|
|
12
|
+
desc "Set every lockstep package to one version"
|
|
13
|
+
|
|
14
|
+
argument :version,
|
|
15
|
+
type: :string,
|
|
16
|
+
required: true,
|
|
17
|
+
desc: "Target version, MAJOR.MINOR.PATCH — must not go backwards"
|
|
18
|
+
|
|
19
|
+
example [
|
|
20
|
+
"0.9.0 # move every lockstep package to 0.9.0"
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
# @param version [String, nil] target version
|
|
24
|
+
# @return [void]
|
|
25
|
+
def call(version: nil, **)
|
|
26
|
+
exit(1) unless Inquirex::Tools::VersionBumper.new.call(version)
|
|
27
|
+
rescue Inquirex::Tools::Error => e
|
|
28
|
+
warn "ERROR: #{e.message}"
|
|
29
|
+
exit 1
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Inquirex
|
|
4
|
+
module Tools
|
|
5
|
+
module Commands
|
|
6
|
+
# `inquirex versions-check` — reports the family's lockstep version.
|
|
7
|
+
#
|
|
8
|
+
# Plural on purpose: `inquirex version` prints this tool's own version,
|
|
9
|
+
# `inquirex versions-check` reports the family's. Read-only; the write
|
|
10
|
+
# counterpart is `inquirex versions-bump`.
|
|
11
|
+
class VersionsCheck < Dry::CLI::Command
|
|
12
|
+
desc "Report lockstep version parity across the family"
|
|
13
|
+
|
|
14
|
+
option :preflight,
|
|
15
|
+
type: :boolean,
|
|
16
|
+
default: false,
|
|
17
|
+
desc: "Also check clean trees, main branch, and tags"
|
|
18
|
+
|
|
19
|
+
example [
|
|
20
|
+
" # report parity, exit 1 on drift",
|
|
21
|
+
"--preflight # release readiness"
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
# @param preflight [Boolean] also report git release readiness
|
|
25
|
+
# @return [void]
|
|
26
|
+
def call(preflight: false, **)
|
|
27
|
+
checker = Inquirex::Tools::VersionChecker.new
|
|
28
|
+
exit(1) unless preflight ? checker.preflight : checker.call
|
|
29
|
+
rescue Inquirex::Tools::Error => e
|
|
30
|
+
warn "ERROR: #{e.message}"
|
|
31
|
+
exit 1
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
require "dry/cli"
|
|
4
4
|
|
|
5
5
|
require_relative "commands/version"
|
|
6
|
-
require_relative "commands/
|
|
6
|
+
require_relative "commands/versions_bump"
|
|
7
|
+
require_relative "commands/versions_check"
|
|
8
|
+
require_relative "commands/publish"
|
|
7
9
|
require_relative "commands/changelogs"
|
|
8
10
|
|
|
9
11
|
module Inquirex
|
|
@@ -16,9 +18,11 @@ module Inquirex
|
|
|
16
18
|
module Commands
|
|
17
19
|
extend Dry::CLI::Registry
|
|
18
20
|
|
|
19
|
-
register "versions",
|
|
21
|
+
register "versions-check", VersionsCheck
|
|
22
|
+
register "versions-bump", VersionsBump
|
|
23
|
+
register "publish", Publish
|
|
20
24
|
register "changelogs", Changelogs
|
|
21
|
-
register "version",
|
|
25
|
+
register "version", Version
|
|
22
26
|
end
|
|
23
27
|
end
|
|
24
28
|
end
|