Skip to content

Commit a3e7b32

Browse files
committed
fix: writes
1 parent 50d636f commit a3e7b32

File tree

5 files changed

+100
-29
lines changed

5 files changed

+100
-29
lines changed

.github/workflows/shiplog-sign.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ permissions:
2929
jobs:
3030
sign-entry:
3131
runs-on: ubuntu-latest
32+
environment:
33+
name: ${{ github.event_name == 'workflow_dispatch' && inputs.env || 'prod' }}
3234
steps:
3335
- name: Checkout
3436
uses: actions/checkout@v4
@@ -45,7 +47,7 @@ jobs:
4547
- name: Configure SSH signing (CI)
4648
env:
4749
CI_SSH_PRIVATE_KEY: ${{ secrets.CI_SSH_PRIVATE_KEY }}
48-
CI_SSH_PUBLIC_KEY: ${{ env.CI_SSH_PUBLIC_KEY }}
50+
CI_SSH_PUBLIC_KEY: ${{ vars.CI_SSH_PUBLIC_KEY }}
4951
run: |
5052
set -euo pipefail
5153
[ -n "${CI_SSH_PRIVATE_KEY:-}" ] || { echo "Missing CI_SSH_PRIVATE_KEY secret" >&2; exit 1; }
@@ -94,4 +96,3 @@ jobs:
9496
run: |
9597
set -euo pipefail
9698
git push origin "refs/_shiplog/journal/${SHIPLOG_ENV}"
97-

docs/features/write.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,25 @@
55

66
## Usage
77
```bash
8-
git shiplog write [ENV]
9-
# non-interactive
10-
SHIPLOG_BORING=1 git shiplog --yes write prod
8+
git shiplog write [ENV] \
9+
[--service NAME] [--status success|failed|in_progress|skipped|override|revert|finalize] \
10+
[--reason TEXT] [--ticket ID] \
11+
[--region R] [--cluster C] [--namespace NS] \
12+
[--image IMG] [--tag TAG] [--run-url URL]
13+
14+
# Non-interactive
15+
SHIPLOG_BORING=1 git shiplog --yes write prod --service release --reason "MVP release"
1116
```
1217

1318
## Behavior
1419
- Validates the author against the resolved allowlist and performs a signing precheck when signatures are required.
15-
- Prompts for service, status, change details, and artifact information; respects the `SHIPLOG_*` environment overrides listed below.
20+
- Prompts for service, status, change details, and artifact information. You can prefill or bypass prompts with flags (`--service`, `--reason`, etc.) or environment variables listed below.
1621
- Generates both a human-readable header and a JSON trailer; optionally attaches NDJSON logs via `SHIPLOG_LOG`.
1722
- Accepts `--yes` to skip confirmation prompts (sets `SHIPLOG_ASSUME_YES=1`).
1823
- Fast-forwards the journal ref; aborts if the ref is missing or would require a force update.
1924
- Automatically pushes the updated journal (and attached notes) to `origin` when available; disable with `SHIPLOG_AUTO_PUSH=0` or `--no-push`.
2025

21-
## Environment Overrides
26+
## Flags and Environment Overrides
2227
| Variable | Purpose | Accepted values | Default | Example |
2328
|----------|---------|-----------------|---------|---------|
2429
| `SHIPLOG_ENV` | Target environment when `[ENV]` argument omitted | Any journal name | `prod` | `SHIPLOG_ENV=staging` |

lib/commands.sh

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,45 @@ cmd_init() {
176176

177177
cmd_write() {
178178
ensure_in_repo
179-
local env="${1:-$DEFAULT_ENV}"
179+
local env="$DEFAULT_ENV"
180+
local args=()
181+
local opt
182+
183+
# Parse positional ENV and optional flags to prefill prompts
184+
while [ $# -gt 0 ]; do
185+
case "$1" in
186+
--env)
187+
shift; env="${1:-$env}"; shift; continue ;;
188+
--env=*)
189+
env="${1#*=}"; shift; continue ;;
190+
--service) shift; SHIPLOG_SERVICE="${1:-}"; export SHIPLOG_SERVICE; shift; continue ;;
191+
--service=*) SHIPLOG_SERVICE="${1#*=}"; export SHIPLOG_SERVICE; shift; continue ;;
192+
--status) shift; SHIPLOG_STATUS="${1:-}"; export SHIPLOG_STATUS; shift; continue ;;
193+
--status=*) SHIPLOG_STATUS="${1#*=}"; export SHIPLOG_STATUS; shift; continue ;;
194+
--reason) shift; SHIPLOG_REASON="${1:-}"; export SHIPLOG_REASON; shift; continue ;;
195+
--reason=*) SHIPLOG_REASON="${1#*=}"; export SHIPLOG_REASON; shift; continue ;;
196+
--ticket) shift; SHIPLOG_TICKET="${1:-}"; export SHIPLOG_TICKET; shift; continue ;;
197+
--ticket=*) SHIPLOG_TICKET="${1#*=}"; export SHIPLOG_TICKET; shift; continue ;;
198+
--region) shift; SHIPLOG_REGION="${1:-}"; export SHIPLOG_REGION; shift; continue ;;
199+
--region=*) SHIPLOG_REGION="${1#*=}"; export SHIPLOG_REGION; shift; continue ;;
200+
--cluster) shift; SHIPLOG_CLUSTER="${1:-}"; export SHIPLOG_CLUSTER; shift; continue ;;
201+
--cluster=*) SHIPLOG_CLUSTER="${1#*=}"; export SHIPLOG_CLUSTER; shift; continue ;;
202+
--namespace) shift; SHIPLOG_NAMESPACE="${1:-}"; export SHIPLOG_NAMESPACE; shift; continue ;;
203+
--namespace=*) SHIPLOG_NAMESPACE="${1#*=}"; export SHIPLOG_NAMESPACE; shift; continue ;;
204+
--image) shift; SHIPLOG_IMAGE="${1:-}"; export SHIPLOG_IMAGE; shift; continue ;;
205+
--image=*) SHIPLOG_IMAGE="${1#*=}"; export SHIPLOG_IMAGE; shift; continue ;;
206+
--tag) shift; SHIPLOG_TAG="${1:-}"; export SHIPLOG_TAG; shift; continue ;;
207+
--tag=*) SHIPLOG_TAG="${1#*=}"; export SHIPLOG_TAG; shift; continue ;;
208+
--run-url) shift; SHIPLOG_RUN_URL="${1:-}"; export SHIPLOG_RUN_URL; shift; continue ;;
209+
--run-url=*) SHIPLOG_RUN_URL="${1#*=}"; export SHIPLOG_RUN_URL; shift; continue ;;
210+
--) shift; break ;;
211+
-*) args+=("$1"); shift; continue ;;
212+
*)
213+
# First non-flag positional argument is ENV if not set by --env
214+
if [ "$env" = "$DEFAULT_ENV" ]; then env="$1"; shift; continue; else args+=("$1"); shift; continue; fi
215+
;;
216+
esac
217+
done
180218

181219
require_allowed_author
182220
require_allowed_signer

lib/common.sh

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,20 @@ shiplog_prompt_input() {
112112
if is_boring; then
113113
printf '%s\n' "$value"
114114
else
115-
shiplog_require_bosun
116-
local result
117-
local bosun
118-
bosun=$(shiplog_bosun_bin)
119-
result=$("$bosun" input --placeholder "$placeholder" --value "$value")
115+
local result=""
116+
if shiplog_have_bosun; then
117+
local bosun
118+
bosun=$(shiplog_bosun_bin)
119+
if result=$("$bosun" input --placeholder "$placeholder" --value "$value" 2>/dev/null); then
120+
printf '%s\n' "$result"
121+
_log_prompt_interaction prompt "$placeholder" "$result"
122+
return
123+
fi
124+
fi
125+
# Fallback to POSIX prompt
126+
printf '%s ' "$placeholder" >&2
127+
IFS= read -r result || result="$value"
128+
[ -n "$result" ] || result="$value"
120129
printf '%s\n' "$result"
121130
_log_prompt_interaction prompt "$placeholder" "$result"
122131
fi
@@ -138,14 +147,21 @@ shiplog_prompt_choice() {
138147
if is_boring; then
139148
printf '%s\n' "$value"
140149
else
141-
shiplog_require_bosun
142-
local result
143-
local bosun
144-
bosun=$(shiplog_bosun_bin)
145-
if [ -n "$value" ]; then
146-
result=$("$bosun" choose --header "$header" --default "$value" "${options[@]}")
147-
else
148-
result=$("$bosun" choose --header "$header" "${options[@]}")
150+
local result=""
151+
if shiplog_have_bosun; then
152+
local bosun
153+
bosun=$(shiplog_bosun_bin)
154+
if [ -n "$value" ]; then
155+
result=$("$bosun" choose --header "$header" --default "$value" "${options[@]}" 2>/dev/null) || true
156+
else
157+
result=$("$bosun" choose --header "$header" "${options[@]}" 2>/dev/null) || true
158+
fi
159+
fi
160+
if [ -z "$result" ]; then
161+
# Fallback: print options and read a line
162+
printf '%s [%s] ' "$header" "${options[*]}" >&2
163+
IFS= read -r result || result="$value"
164+
[ -n "$result" ] || result="$value"
149165
fi
150166
printf '%s\n' "$result"
151167
_log_prompt_interaction prompt "$header" "$result"
@@ -159,13 +175,17 @@ shiplog_confirm() {
159175
return 0
160176
fi
161177
_log_prompt_interaction confirmation "$prompt" null raw
162-
shiplog_require_bosun
163-
local bosun
164-
bosun=$(shiplog_bosun_bin)
165-
if "$bosun" confirm "$prompt"; then
178+
if shiplog_have_bosun && "$(shiplog_bosun_bin)" confirm "$prompt"; then
166179
_log_prompt_interaction confirmation "$prompt" true raw
167180
return 0
168181
fi
182+
# Fallback
183+
printf '%s [y/N] ' "$prompt" >&2
184+
local ans
185+
IFS= read -r ans || ans=""
186+
case "$(printf '%s' "$ans" | tr '[:upper:]' '[:lower:]')" in
187+
y|yes) _log_prompt_interaction confirmation "$prompt" true raw; return 0 ;;
188+
esac
169189
_log_prompt_interaction confirmation "$prompt" false raw
170190
return 1
171191
}

lib/git.sh

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,13 +154,20 @@ sign_commit() {
154154
local sign_mode="${SHIPLOG_SIGN_EFFECTIVE:-0}"
155155
GIT_AUTHOR_NAME="${GIT_AUTHOR_NAME:-${SHIPLOG_AUTHOR_NAME:-$(git config user.name || echo 'Shiplog Bot')}}"
156156
GIT_AUTHOR_EMAIL="${GIT_AUTHOR_EMAIL:-${SHIPLOG_AUTHOR_EMAIL:-$(git config user.email || echo 'shiplog-bot@local')}}"
157-
local signer_flag=()
157+
158+
# Build commit-tree command safely without expanding an empty array under set -u
159+
local -a cmd
160+
cmd=(git commit-tree "$tree")
158161
case "$sign_mode" in
159-
0|false|no|off) ;;
160-
*) signer_flag=(-S) ;;
162+
0|false|no|off) : ;;
163+
*) cmd+=(-S) ;;
161164
esac
165+
# Append remaining arguments (e.g., -p <parent>)
166+
if [ "$#" -gt 0 ]; then
167+
cmd+=("$@")
168+
fi
162169
GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME" GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL" \
163-
git commit-tree "$tree" "$@" "${signer_flag[@]}"
170+
"${cmd[@]}"
164171
}
165172

166173
attach_note_if_present() {

0 commit comments

Comments
 (0)