Skip to content

Commit 372e688

Browse files
committed
chore: move gmpctl to ops/
1 parent 5cc808d commit 372e688

23 files changed

+476
-219
lines changed

hack/gmpctl.sh

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,4 @@ SCRIPT_DIR="$(
2626
pwd -P
2727
)"
2828

29-
pushd "${SCRIPT_DIR}/gmpctl" >/dev/null
30-
# NOTE gmpctl expects the whole gmpctl directory to be present.
31-
# We could consider embedding bash scripts, config into binary, but it's good
32-
# for now.
33-
go run ./ "$@"
34-
popd >/dev/null
29+
bash "${SCRIPT_DIR}/../ops/gmpctl.sh" "$@"

hack/presubmit.sh

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ warn() {
3838
echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: Warning: $*" >&2
3939
}
4040

41-
REPO_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
41+
REPO_ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." &>/dev/null && pwd)
4242
CRD_DIR=${REPO_ROOT}/charts/operator/crds
4343
SED=$(which gsed 2>/dev/null || which sed)
4444

@@ -124,18 +124,28 @@ run_tests() {
124124
}
125125

126126
reformat() {
127-
echo ">>> reformatting"
128-
go mod tidy
127+
find . -name "go.mod" | grep -v gmpctl/data | grep -v ".bingo" | while read -r file; do
128+
dir=$(dirname "$file")
129+
pushd "${dir}"
130+
echo ">>> go mod tidy $dir"
131+
go mod tidy
132+
popd
133+
done
134+
135+
echo ">>> formatting Go files"
129136
pushd "${REPO_ROOT}"
130137
go fmt ./...
131138
popd
132139

133-
pushd "${REPO_ROOT}/hack/"
140+
echo ">>> formatting docs"
141+
pushd "${REPO_ROOT}/ops/gmpctl"
134142
go mod download # get all deps to avoid garbage output on <command> --help when auto-generating docs.
135143
popd
136-
${MDOX} fmt --soft-wraps "${REPO_ROOT}"/*.md "${REPO_ROOT}"/cmd/**/*.md "${REPO_ROOT}"/hack/gmpctl/*.md
144+
${MDOX} fmt --soft-wraps "${REPO_ROOT}"/*.md "${REPO_ROOT}"/cmd/**/*.md "${REPO_ROOT}"/ops/gmpctl/*.md
145+
146+
echo ">>> formatting bash scripts"
137147
# TODO: Fix and apply this to all .sh scripts we host.
138-
${SHFMT} -l -w "${REPO_ROOT}/hack/gmpctl/lib.sh" "${REPO_ROOT}/hack/presubmit.sh"
148+
${SHFMT} -l -w "${REPO_ROOT}/ops/gmpctl/lib.sh" "${REPO_ROOT}/hack/presubmit.sh"
139149
}
140150

141151
exit_msg() {

ops/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
### ops
2+
3+
This directory contains scripts and automation for common GMP dev operations.
4+
5+
Resources in `/ops` are meant to be used in the latest form (the `main` branch). Notably,
6+
when using those scripts in CI, use the latest version in main branch.
7+

ops/gmpctl.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2025 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
set -o errexit
17+
set -o pipefail
18+
set -o nounset
19+
20+
if [[ -n "${DEBUG_MODE:-}" ]]; then
21+
set -o xtrace
22+
fi
23+
24+
SCRIPT_DIR="$(
25+
cd -- "$(dirname "$0")" >/dev/null 2>&1
26+
pwd -P
27+
)"
28+
29+
# NOTE gmpctl expects the gmpctl directory to be present on execution for
30+
# local bash scripts and configuration.
31+
#
32+
# We could consider embedding bash scripts, config into binary for portability,
33+
# but it's good enough for now.
34+
35+
pushd "${SCRIPT_DIR}/gmpctl" >/dev/null
36+
go run ./ "$@"
37+
popd >/dev/null
Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@ It's a starting point for smaller or bigger automation on OSS side (e.g. releasi
1414

1515
2. The next this is to obtain NVD API key to avoid rate-limits when querying CVE DB. See https://nvd.nist.gov/developers/request-an-api-key and save this key to `hack/vulnupdatelist/api.text`
1616

17-
3. You can configure different work directory for gmpctl via `-c` flag. By default, `gmpctl` does the work in `hack/gmpctl/.data`)
17+
3. Ensure you have installed:
18+
* new-ish `bash` (MacOS: `brew install bash`)
19+
* `gsed` (MacOS: `brew install gsed`)
20+
* `gcloud` (https://docs.cloud.google.com/sdk/docs/install-sdk) (and `gcloud auth login`)
21+
* `gpg` (MacOS: `brew install gpg`)
22+
23+
4. You can configure different work directory for gmpctl via `-c` flag. By default, `gmpctl` does the work in `hack/gmpctl/.data`)
1824

1925
Enjoy!
2026

@@ -45,6 +51,8 @@ on breaking go mod updates for vulnerabilities or fork sync conflicts.
4551
Usage: gmpctl [COMMAND] [FLAGS]
4652
-c string
4753
Path to the configuration file. See config.go#Config for the structure. (default ".gmpctl.default.yaml")
54+
-git.prefer-https
55+
If true, uses HTTPS protocol instead of git for remote URLs.
4856
-v Enabled verbose, debug output (e.g. logging os.Exec commands)
4957

5058
--- Commands ---
@@ -98,10 +106,11 @@ Some rules to follow:
98106
* Ensure all error messages are redirected to stderr, use log_err func for this.
99107
* Be careful with pushd/popd which log to stdout, you can redirect those to stderr too.
100108

101-
## TODO
109+
## TODO / Known issues.
102110

103-
* Ability to configure NVD API key in gmpctl config.
104-
* Port fork-sync script from the old PR.
105-
* Generate some on-demand query of vulnerabilities for all releases (aka dashboard.)
106-
* Fix NPM vulns (although it's rate).
107-
* Ability to schedule multiple scripts at once and managing that? (lot's of work vs multiple terminals)
111+
* [ ] Port bash to Go for stable commands.
112+
* [ ] Ability to configure NVD API key in gmpctl config.
113+
* [ ] Port fork-sync script from the old PR.
114+
* [ ] Generate some on-demand query of vulnerabilities for all releases (aka dashboard.)
115+
* [ ] Fix NPM vulns (although it's rate).
116+
* [ ] Ability to schedule multiple scripts at once and managing that? (lot's of work vs multiple terminals)
Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func release() error {
4949
return fmt.Errorf("couldn't find project from branch %s", branch)
5050
}
5151

52-
logf("Assuming %q with remote %q; branch to release: %q", proj.Name, proj.RemoteURL, branch)
52+
logf("Assuming %q with remote %q; branch to release: %q", proj.Name, proj.RemoteURL(), branch)
5353
dir := proj.WorkDir(cfg.Directory, branch, "release")
5454

5555
mustFetchAll(dir)
@@ -66,35 +66,39 @@ func release() error {
6666
}
6767
logf("Selected %v tag", tag)
6868

69-
if err := runLibFunction(dir, []string{
69+
if err := runLocalBash(dir, []string{
7070
fmt.Sprintf("DIR=%v", dir),
7171
fmt.Sprintf("BRANCH=%v", branch),
7272
fmt.Sprintf("PROJECT=%v", proj.Name),
7373
fmt.Sprintf("TAG=%v", tag),
74-
}, "release-lib::pre-release-rc"); err != nil {
74+
}, "prep-rc.sh"); err != nil {
7575
return err
7676
}
7777

7878
msg := fmt.Sprintf("chore: prepare for %v release", tag)
7979
// TODO(bwplotka): Port to Go, make it more reliable.
8080
// TODO(bwplotka): Quote otherwise it's split into separate args... port it so it works better (:
81+
// TODO(bwplotka): Add message about a script command.
8182
if err := runLibFunction(dir, nil, "release-lib::idemp::git_commit_amend_match", "\""+msg+"\""); err != nil {
8283
return err
8384
}
8485

86+
if !mustIsRemoteUpToDate(dir, branch) {
87+
if confirmf("About to git push state from %q to \"origin/%v\" for %q tag; are you sure?", dir, branch, tag) {
88+
// We are in detached state, so use the HEAD reference.
89+
mustPush(dir, fmt.Sprintf("HEAD:%v", branch))
90+
} else {
91+
return errors.New("aborting")
92+
}
93+
}
94+
8595
// TODO(bwplotka): Check if tag exists.
8696
mustCreateSignedTag(dir, tag)
87-
88-
// TODO check if anything is needed to push?
89-
// TODO(bwplotka): Add option to print more debug/open terminal with the workdir?
90-
if confirmf("About to git push state from %q to \"origin/%v\"; then push %q tag; are you sure?", dir, branch, tag) {
91-
// We are in detached state
92-
mustPush(dir, fmt.Sprintf("HEAD:%v", branch))
97+
if confirmf("About to git push %q tag from %q to \"origin/%v\"; are you sure?", tag, dir, branch) {
9398
mustPush(dir, tag)
9499
} else {
95100
return errors.New("aborting")
96101
}
97-
98102
if confirmf("Do you want to remove the %v worktree (recommended)?", dir) {
99103
proj.RemoveWorkDir(cfg.Directory, dir)
100104
}
Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func vulnfix() error {
6868
prBranch = fmt.Sprintf("%v/%v-gmpctl-vulnfix", os.Getenv("USER"), branch)
6969
}
7070

71-
logf("Assuming %q with remote %q; on %q; changes will be pushed to %q", proj.Name, proj.RemoteURL, branch, prBranch)
71+
logf("Assuming %q with remote %q; on %q; changes will be pushed to %q", proj.Name, proj.RemoteURL(), branch, prBranch)
7272
dir := proj.WorkDir(cfg.Directory, branch, "vulnfix")
7373

7474
// Refresh.
@@ -84,7 +84,7 @@ func vulnfix() error {
8484
}
8585

8686
// TODO(bwplotka): Add NPM vulnfix.
87-
if err := runLibFunction(dir, opts, "release-lib::vulnfix"); err != nil {
87+
if err := runLocalBash(dir, opts, "vulnfix.sh"); err != nil {
8888
return err
8989
}
9090

@@ -100,10 +100,14 @@ func vulnfix() error {
100100
if err := runLibFunction(dir, nil, "release-lib::idemp::git_commit_amend_match", "\""+msg+"\""); err != nil {
101101
return err
102102
}
103-
// TODO(bwplotka): Check if needs pushing?
103+
104+
if mustIsRemoteUpToDate(dir, branch) {
105+
return fmt.Errorf("nothing to push from %q to \"origin/%v\"; aborting", dir, prBranch)
106+
}
107+
104108
// TODO(bwplotka): Add option to print more debug/open terminal with the workdir?
105109
if confirmf("About to FORCE git push state from %q to \"origin/%v\"; are you sure?", dir, prBranch) {
106-
// We are in detached state, so be explicit what to push and from where.
110+
// We are in detached state, so be explicit what to push and from where, by recreating the local prBranch.
107111
mustRecreateBranch(dir, prBranch)
108112
mustForcePush(dir, prBranch)
109113
} else {

0 commit comments

Comments
 (0)