-
-
Notifications
You must be signed in to change notification settings - Fork 0
chore(ci): repoint push-email-notify to smtp-notify-action #79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,19 +3,43 @@ | |
| # PUSH_EMAIL_ENABLED=true (the single on/off switch). Addresses are pre-filled; | ||
| # sending needs the org SMTP secrets (SMTP_HOST/PORT/USER/PASS). Inherited by | ||
| # new repos from the template; placed on existing repos by the farm sweep. | ||
| # | ||
| # Re-landed after the 2026-07-20 notification-storm freeze (removed in | ||
| # 09f94c5), now on hyperpolymath/smtp-notify-action: Node-free, the SMTP | ||
| # session is Idris2-specified and machine-checked, the binary is Zig-built, | ||
| # byte-reproducible, and SHA-256-pinned inside the action itself. | ||
| name: Push email notification | ||
| on: | ||
| push: {} | ||
| push: | ||
| # Branch pushes only: tag and deletion payloads mislabel Branch:/head_commit. | ||
| branches: ['**'] | ||
| concurrency: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- workflow ---'
cat -n .github/workflows/push-email-notify.yml
printf '%s\n' '--- relevant diff ---'
git diff -- .github/workflows/push-email-notify.yml
printf '%s\n' '--- repository conventions and architecture references ---'
trueRepository: hyperpolymath/checky-monkey Length of output: 3505 🤖 get_repo_knowledge executed:
Length of output: 2637 🌐 Web query:
💡 Result: In GitHub Actions, using the permissions: {} syntax within a workflow or job configuration explicitly removes all permissions from the GITHUB_TOKEN, with the exception of the metadata scope, which always retains read access [1][2]. When you define the permissions key in your workflow file, GitHub sets all unspecified permissions to none (no access) [3][1]. By setting permissions to an empty object ({}), you are effectively stripping the GITHUB_TOKEN of all capabilities except for the mandatory metadata access, ensuring the most restrictive, least-privileged environment for that workflow or job [4][2]. Key points regarding this behavior: - Exclusivity: Because this key is present, GitHub does not fall back to the default repository or organization-level permissions for any scope other than metadata [1][2]. - Security: This is a recommended security practice for workflows or jobs that do not require any interaction with the repository or external GitHub services [4][5]. - Overriding: If you need to grant specific access while keeping everything else restricted, you must explicitly list those permissions (e.g., contents: read) within the permissions block [3][6]. This behavior applies to both workflow-level and job-level definitions [1][6]. If defined at the workflow level, it applies to all jobs in that workflow unless overridden by a more specific job-level permissions key [1][6]. Citations:
Remove the unnecessary This workflow grants 🤖 Prompt for AI Agents |
||
| # Deliberately per-RUN, so no run is ever queued behind another and none is | ||
| # ever cancelled. Do NOT "tidy" this into a shared group such as | ||
| # ${{ github.workflow }}-${{ github.ref }}. GitHub's workflow-syntax docs: | ||
| # "By default, any existing pending job or workflow in the same concurrency | ||
| # group will be canceled and the new queued job or workflow will take its | ||
| # place." That happens regardless of cancel-in-progress, which governs only | ||
| # the RUNNING job. On this workflow it silently loses a notification email, | ||
| # with no error anywhere. Every run here reports a DISTINCT commit, so there | ||
| # is no redundant work for a concurrency limit to remove. | ||
| # The docs also offer `queue: max` (up to 100 pending); not used, because 100 | ||
| # is still a cap whereas a per-run group needs none. | ||
| # Verified with zizmor 1.30.0: deleting this block raises concurrency-limits; | ||
| # this form silences it exactly as a shared group would. | ||
| group: push-email-${{ github.run_id }} | ||
| cancel-in-progress: false | ||
| permissions: | ||
| contents: read | ||
| jobs: | ||
| notify: | ||
| name: Email on push | ||
| if: ${{ vars.PUSH_EMAIL_ENABLED == 'true' }} | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 5 | ||
| steps: | ||
| - name: Send push notification email | ||
| uses: dawidd6/action-send-mail@0bbdab096651ee93f37ec02383e088183d41ff0b # pinned | ||
| uses: hyperpolymath/smtp-notify-action@ede1191ef6ff3ac02c4f4d9efdf837ee517e11d7 # v0.2.0 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- workflow ---'
cat -n .github/workflows/push-email-notify.yml | sed -n '34,48p'
printf '%s\n' '--- repository references to the action and release claims ---'
rg -n -S 'smtp-notify-action|v0\.1\.0|v0\.2\.0|1b3b752d39a4fe4c0f28f10905e4608789d3e050|ede1191ef6ff3ac02c4f4d9efdf837ee517e11d7' .github README.md 2>/dev/null || true
printf '%s\n' '--- tag and commit resolution ---'
python3 - <<'PY'
import json
import urllib.request
import urllib.error
repo = "hyperpolymath/smtp-notify-action"
pins = [
"1b3b752d39a4fe4c0f28f10905e4608789d3e050",
"ede1191ef6ff3ac02c4f4d9efdf837ee517e11d7",
]
tags = ["v0.1.0", "v0.2.0"]
def get(path):
req = urllib.request.Request(
"https://api.github.com/" + path,
headers={"Accept": "application/vnd.github+json", "User-Agent": "verification"},
)
try:
with urllib.request.urlopen(req, timeout=15) as r:
return r.status, json.load(r)
except urllib.error.HTTPError as e:
return e.code, e.read().decode()
for tag in tags:
status, ref = get(f"repos/{repo}/git/ref/tags/{tag}")
print(f"TAG {tag} status={status}")
if status != 200:
print(ref)
continue
obj = ref["object"]
print(f" ref_object type={obj['type']} sha={obj['sha']}")
if obj["type"] == "tag":
status2, tag_obj = get(f"repos/{repo}/git/tags/{obj['sha']}")
print(f" dereference status={status2}")
if status2 == 200:
print(f" commit_sha={tag_obj['object']['sha']}")
else:
print(tag_obj)
else:
print(f" commit_sha={obj['sha']}")
for pin in pins:
status, result = get(f"repos/{repo}/commits/{pin}")
print(f"PIN {pin} status={status}")
if status == 200:
print(f" resolved_sha={result['sha']}")
print(f" message={result['commit']['message'].splitlines()[0]}")
else:
print(result)
PYRepository: hyperpolymath/checky-monkey Length of output: 3476 🤖 get_repo_knowledge executed:
Length of output: 2637 🏁 Script executed: #!/bin/bash
set -eu
repo='hyperpolymath/smtp-notify-action'
api="https://api.github.com/repos/${repo}"
api_get() {
curl --fail --silent --show-error --insecure \
-H 'Accept: application/vnd.github+json' \
-H 'User-Agent: checky-monkey-review' \
"$1"
}
for tag in v0.1.0 v0.2.0; do
echo "TAG $tag"
ref="$(api_get "$api/git/ref/tags/$tag")"
printf '%s\n' "$ref" | jq -r '"ref_object type=\(.object.type) sha=\(.object.sha)"'
type="$(printf '%s\n' "$ref" | jq -r '.object.type')"
sha="$(printf '%s\n' "$ref" | jq -r '.object.sha')"
if [ "$type" = tag ]; then
tag_obj="$(api_get "$api/git/tags/$sha")"
printf '%s\n' "$tag_obj" | jq -r '"commit_sha=\(.object.sha) object_type=\(.object.type)"'
else
echo "commit_sha=$sha object_type=$type"
fi
done
for pin in \
1b3b752d39a4fe4c0f28f10905e4608789d3e050 \
ede1191ef6ff3ac02c4f4d9efdf837ee517e11d7
do
echo "PIN $pin"
api_get "$api/commits/$pin" | jq -r '"resolved_sha=\(.sha)\nmessage=\(.commit.message | split("\n")[0])"'
doneRepository: hyperpolymath/checky-monkey Length of output: 813 Align the action pin with the intended release. The workflow pins v0.2.0 at 🤖 Prompt for AI Agents |
||
| with: | ||
| server_address: ${{ secrets.SMTP_HOST }} | ||
| server_port: ${{ secrets.SMTP_PORT }} | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: hyperpolymath/checky-monkey
Length of output: 2579
🏁 Script executed:
Repository: hyperpolymath/checky-monkey
Length of output: 2663
🌐 Web query:
GitHub Actions workflow syntax push branches filter branch deletion deleted event payload head_commit💡 Result:
When you delete a Git branch, GitHub sends a push event to the repository with a payload indicating the reference was deleted, which can inadvertently trigger workflows configured with
on: push[1][2][3]. 1. Push event and branch deletion: When a branch is deleted, GitHub triggers apushevent [1][3]. In this event's payload, thedeletedattribute is set totrue[4]. Consequently, if a workflow is configured to run onpushwithout specific filters that account for this, it may execute unintentionally [2]. When this happens, theGITHUB_SHAassociated with the workflow run typically reverts to the commit SHA of the default branch of the repository [1][3]. 2. Workflow syntax filtering: You cannot explicitly "filter out" branch deletion directly within the standardbranchesorbranches-ignoresyntax in the same way you filter branch names [5][6]. To prevent workflows from running on branch deletion, developers often use conditional steps within the workflow to check the event payload: - Example check:if: ${{ !github.event.deleted }}[4]. 3. 'delete' event: There is a distinctdeleteevent in GitHub Actions that triggers when a Git reference (branch or tag) is deleted [3]. Unlike thepushevent, this requires explicit configuration (on: delete) [3][7]. A critical constraint is that the workflow file containing thedeletetrigger must exist on the repository's default branch to be executed [3][8]. 4. Payload details: Thehead_commitobject is typically present in push event payloads [4]. However, when a branch is deleted, the context of the push event is fundamentally different from a standard code push, as it represents the removal of a reference rather than the introduction of new commits [1][3]. Relying onhead_commitduring a branch deletion push event may yield the commit SHA of the default branch, not the former tip of the deleted branch [1][3].Citations:
Exclude deleted branch push events.
branches: ['**']also matches branch deletion push events. Whengithub.event.deletedistrue,github.event.head_commitis unavailable, but the job still sends an email whenPUSH_EMAIL_ENABLEDistrue. Addgithub.event.deleted != trueto the job condition.🧰 Tools
🪛 zizmor (1.29.0)
[warning] 12-15: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
🤖 Prompt for AI Agents
🩺 Stability & Availability | 🔵 Trivial
🔎 Supported by static analysis
🏁 Script executed:
Repository: hyperpolymath/checky-monkey
Length of output: 5200
🌐 Web query:
GitHub Actions concurrency default concurrent workflow runs permitted documentation💡 Result:
By default, GitHub Actions allows multiple workflow runs and jobs to execute concurrently without restrictions [1][2]. There is no default limit on the number of concurrent workflow runs permitted for a repository or account [1][3]. If you wish to limit concurrency for specific workflows, you can use the
concurrencykeyword [4][5]. When this keyword is used: 1. Only one job or workflow in a specific concurrency group is permitted to run at any given time [4][6]. 2. If a new workflow or job is triggered while another is already running in that group, the new one will be set to pending [4][5]. 3. By default (with thesinglequeue setting), any existingpendingjob or workflow in the same concurrency group will be canceled when a new one is queued [4][3]. 4. Alternatively, you can usequeue: maxto allow up to 100 jobs or workflow runs to remain in apendingstate for that concurrency group [5][6]. While there is no inherent limit on concurrent runs by default, actual execution is still subject to your account's or organization's available runner resources and usage limits [3].Citations:
Define concurrency if notification-storm protection is required
When
PUSH_EMAIL_ENABLEDistrue, this workflow can trigger one SMTP job for each push. GitHub Actions permits concurrent runs by default.timeout-minutes: 5does not limit concurrency. Add a deliberateconcurrencypolicy if this behaviour is not acceptable. Cancellation can suppress intermediate notifications.🧰 Tools
🪛 zizmor (1.29.0)
[warning] 12-15: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
🤖 Prompt for AI Agents
Source: Linters/SAST tools