diff --git a/README.md b/README.md index b6c0749..830cd33 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,9 @@ commits are authored as `[bot]`. Your own `gh` login and git config are unt starts within a couple of minutes. Pitching and discovering happen at most every `dispatch.creativeEvery` minutes, except that the Lead pitches straight away when nothing is Pitched or Exploring, so the stakeholder always has a pitch to decide on. +- **Dependency updates.** A Dependabot PR the Lead hasn't commented on starts a Lead run. It + reads what the new version brings, files an Idea for each change the product should adopt (a + style guide's new rule, say), and lists them on the PR. Merging the PR stays yours. - **Feedback is never too old to start a run.** The two-minute check reads the last day of comments repo-wide, so every `dispatch.sweepEvery` minutes (30 by default) a role's own items are read in full instead, however old the comments on them are. The gap is elapsed time, not diff --git a/roles/lead.md b/roles/lead.md index 6430b5f..120628d 100644 --- a/roles/lead.md +++ b/roles/lead.md @@ -101,7 +101,20 @@ For each item in `a-team board {{team}} mine lead Building`, run `children`: two what you tried. The stakeholder has already tried and merged every task, so the pitch doesn't come back to them. -### 4. Swap Pitched, then pitch or discover +### 4. Read dependency updates + +For each Dependabot PR your prompt names: + +- Read what the new version brings: the release notes in the PR, and the changes they link to. + Where the contributor docs say the dependency carries the product's conventions, like a style + guide's library, look for rules that are new or changed. +- For each change the product should adopt and doesn't follow yet, file an Idea as in `discover` + below, naming the PR under **Evidence**. If the update needs code changes before it builds, say + so in the Idea: that work ships inside it. +- Then `a-team board {{team}} comment lead `, listing the Ideas you filed, or saying + there's nothing to adopt. Leave the PR itself to the stakeholder. + +### 5. Swap Pitched, then pitch or discover Run `a-team board {{team}} lead-next` once. It returns the pitches to show the stakeholder now, and whether this run's new work is a pitch or a discovery. It alternates between the two so the stakeholder @@ -194,5 +207,5 @@ the README, the open issues and the code: who it's for, what it's trying to be, deliberately isn't, the products it learns from, and the next few themes. Open it as a draft PR from `a-team/vision` with your marker in the body, then `a-team board {{team}} add lead Pitched`. -Until the stakeholder merges it, only do steps 1 to 3. If the PR is open, answer the stakeholder's +Until the stakeholder merges it, only do steps 1 to 4. If the PR is open, answer the stakeholder's feedback on it (`a-team board {{team}} feedback lead `) by pushing to the branch and replying. diff --git a/scripts/board.sh b/scripts/board.sh index 1ccd51a..467e8d3 100755 --- a/scripts/board.sh +++ b/scripts/board.sh @@ -1350,6 +1350,14 @@ case "$CMD" in [ "${#reasons[@]}" -eq "$had" ] || items+=("$n") done < <(jq -c '.[] | select((.labels | index("pitch")) and .status != "Idea" and .status != "Done")' <<<"$all") + updates=$(gh pr list -R "$REPO" --author app/dependabot --state open --json number,title,comments) + while IFS=$'\t' read -r n title; do + reasons+=("Dependabot opened PR #$n ($title): see what the update brings") + items+=("$n") + done < <(jq -r --arg bot "$(cfg .app.slug)" '.[] + | select(any(.comments[]; .author.login == $bot and (.body | contains(""))) | not) + | [.number, .title] | @tsv' <<<"$updates") + pitched=$(jq '[.[] | select((.labels | index("pitch")) and .status == "Pitched")] | length' <<<"$all") exploring=$(jq '[.[] | select((.labels | index("pitch")) and .status == "Exploring")] | length' <<<"$all") found=$(jq '[.[] | select((.labels | index("a-team:idea")) and .status == "Idea")] | length' <<<"$all") diff --git a/tests/scripts.sh b/tests/scripts.sh index 9fe9b59..833e5c8 100644 --- a/tests/scripts.sh +++ b/tests/scripts.sh @@ -178,6 +178,8 @@ RUNS : >"$FILTERS" CAUGHT="$BIN/caught.json" gh_caught "$UPDATES" cat >"$BIN/gh" <>"$CALLS" @@ -185,6 +187,7 @@ case " \$* " in *addReaction*) printf '%s\n' "\$@" | sed -n 's/^subject=//p' >>"$ACKED"; echo '{}'; exit 0 ;; *updateIssueFieldValue*) printf '%s ' "\$@" | tr -d '\n' >>"$WRITES"; echo >>"$WRITES"; echo '{}'; exit 0 ;; *updateProjectV2ItemFieldValue*) printf '%s ' "\$@" | tr -d '\n' >>"$WRITES"; echo >>"$WRITES"; echo '{}'; exit 0 ;; + *"pr list"*"app/dependabot"*) page="$UPDATES" ;; *ProjectV2SingleSelectField*) page="$META" ;; *issueFields*) page="$FIELDS" ;; *": issue(number"*) jq '{data: {repository: ([.data.organization.projectV2.items.nodes[].content @@ -2216,6 +2219,21 @@ same "chores" '[]' "$(jq -c .chores "$OUT")" run board demo triggers lead same "lead has no tasks" null "$(jq -c .tasks "$OUT")" +case_ "triggers starts the Lead for each Dependabot PR it hasn't commented on yet" +cat >"$UPDATES" <<'JSON' +[{"number": 440, "title": "Bump MentalDesk.Tui", "comments": []}, + {"number": 441, "title": "Bump Terminal.Gui", "comments": [ + {"author": {"login": "demo-app"}, "body": "Nothing to adopt.\n\n"}]}, + {"number": 442, "title": "Bump Spectre.Console", "comments": [ + {"author": {"login": "stranger"}, "body": ""}]}] +JSON +run board demo triggers lead +same "exit" 0 "$STATUS" +same "reasons" '["Dependabot opened PR #440 (Bump MentalDesk.Tui): see what the update brings","Dependabot opened PR #442 (Bump Spectre.Console): see what the update brings"]' \ + "$(jq -c .reasons "$OUT")" +same "items" '[440,442]' "$(jq -c .items "$OUT")" +echo '[]' >"$UPDATES" + # A project whose Status field has the options a claim moves through. claimable() { jq '.data.organization.projectV2.field.options += [{id: "OPT_ready", name: "Ready"}, {id: "OPT_progress", name: "In progress"}]' \