Skip to content

Commit cfd1917

Browse files
committed
build: bring first-time greeting script in-house
--- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: na - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: na - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: passed - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed ---
1 parent 8fe91fb commit cfd1917

File tree

2 files changed

+174
-12
lines changed

2 files changed

+174
-12
lines changed

.github/workflows/first_time_greeting.yml

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,8 @@ jobs:
4444

4545
# Greet first-time contributors:
4646
- name: 'Greet first-time contributors'
47-
# Pin action to full length commit SHA
48-
uses: actions/first-interaction@34f15e814fe48ac9312ccf29db4e74fa767cbab7 # v1.3.0
49-
with:
50-
repo-token: ${{ secrets.STDLIB_BOT_PAT_REPO_WRITE }}
51-
issue-message: |
52-
:wave: Hi there! :wave:
53-
54-
And thank you for opening your first issue! We will get back to you shortly. :runner: :dash:
55-
pr-message: |
56-
:wave: Hi there! :wave:
57-
58-
And thank you for opening your first pull request! We will review it shortly. :runner: :dash:
47+
env:
48+
ISSUE_NUMBER: ${{ github.event.issue.number }}
49+
GITHUB_TOKEN: ${{ secrets.STDLIB_BOT_PAT_REPO_WRITE }}
50+
run: |
51+
. "$GITHUB_WORKSPACE/.github/workflows/scripts/first_time_greeting" $ISSUE_NUMBER
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
#!/usr/bin/env bash
2+
#
3+
# @license Apache-2.0
4+
#
5+
# Copyright (c) 2025 The Stdlib Authors.
6+
#
7+
# Licensed under the Apache License, Version 2.0 (the "License");
8+
# you may not use this file except in compliance with the License.
9+
# You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
19+
# Script to greet first-time contributors.
20+
#
21+
# Usage: first_time_greeting <issue_number>
22+
#
23+
# Arguments:
24+
#
25+
# issue_number Issue or pull request number.
26+
#
27+
# Environment variables:
28+
#
29+
# GITHUB_TOKEN GitHub token for authentication.
30+
31+
# Ensure that the exit status of pipelines is non-zero in the event that at least one of the commands in a pipeline fails:
32+
set -o pipefail
33+
34+
35+
# VARIABLES #
36+
37+
# Resolve the issue or pull request number:
38+
issue_number="$1"
39+
40+
# GitHub API base URL:
41+
github_api_url="https://api.github.com"
42+
43+
# Repository owner and name:
44+
repo_owner="stdlib-js"
45+
repo_name="stdlib"
46+
47+
48+
# FUNCTIONS #
49+
50+
# Error handler.
51+
#
52+
# $1 - error status
53+
on_error() {
54+
echo 'ERROR: An error was encountered during execution.' >&2
55+
exit "$1"
56+
}
57+
58+
# Prints a success message.
59+
print_success() {
60+
echo 'Success!' >&2
61+
}
62+
63+
# Performs a GitHub API request.
64+
#
65+
# $1 - HTTP method (GET or POST)
66+
# $2 - API endpoint
67+
# $3 - data for POST requests
68+
github_api() {
69+
local method="$1"
70+
local endpoint="$2"
71+
local data="$3"
72+
73+
# Initialize an array to hold curl headers:
74+
local headers=()
75+
76+
# If GITHUB_TOKEN is set, add the Authorization header:
77+
if [ -n "${GITHUB_TOKEN}" ]; then
78+
headers+=("-H" "Authorization: token ${GITHUB_TOKEN}")
79+
fi
80+
81+
# Determine the HTTP method and construct the curl command accordingly...
82+
case "${method}" in
83+
GET)
84+
curl -s "${headers[@]}" "${github_api_url}${endpoint}"
85+
;;
86+
POST)
87+
# For POST requests, always set the Content-Type header:
88+
headers+=("-H" "Content-Type: application/json")
89+
90+
# If data is provided, include it in the request:
91+
if [ -n "${data}" ]; then
92+
curl -s -X POST "${headers[@]}" -d "${data}" "${github_api_url}${endpoint}"
93+
else
94+
# Handle cases where POST data is required but not provided:
95+
echo "ERROR: POST request requires data."
96+
on_error 1
97+
fi
98+
;;
99+
*)
100+
echo "ERROR: Invalid HTTP method: ${method}."
101+
on_error 1
102+
;;
103+
esac
104+
}
105+
106+
# Main execution sequence.
107+
main() {
108+
local user_issues
109+
local user_login
110+
local user_prs
111+
local details
112+
local is_pr
113+
114+
if [ -z "${issue_number}" ]; then
115+
echo "ERROR: Issue or pull request number is required." >&2
116+
on_error 1
117+
fi
118+
119+
# Fetch details:
120+
details=$(github_api "GET" "/repos/${repo_owner}/${repo_name}/issues/${issue_number}")
121+
user_login=$(echo "${details}" | jq -r '.user.login')
122+
123+
is_pr=$(echo "$details" | jq -r 'has("pull_request")')
124+
125+
if [ "${is_pr}" = "true" ]; then
126+
# Fetch PRs opened by the user:
127+
user_prs=$(github_api "GET" "/search/issues?q=repo%3A${repo_owner}%2F${repo_name}+author%3A${user_login}+type%3Apr")
128+
129+
# Extract number of PRs by the user:
130+
num_prs=$(echo "${user_prs}" | jq -r '.total_count')
131+
132+
if [ "${num_prs}" = "1" ]; then
133+
# Post a comment on the PR:
134+
comment=":wave: Hi there! :wave:
135+
136+
And thank you for opening your first pull request! We will review it shortly. :runner: :dash:"
137+
if ! github_api "POST" "/repos/${repo_owner}/${repo_name}/issues/${issue_number}/comments" "{\"body\":$(echo "${comment}" | jq -R -s -c .)}"; then
138+
echo "Failed to post comment on PR."
139+
on_error 1
140+
fi
141+
else
142+
echo "PR is not the first contribution from the respective user."
143+
fi
144+
else
145+
# Fetch issues opened by the user:
146+
user_issues=$(github_api "GET" "/search/issues?q=repo%3A${repo_owner}%2F${repo_name}+author%3A${user_login}+type%3Aissue")
147+
148+
# Extract number of issues by the user:
149+
num_issues=$(echo "${user_issues}" | jq -r '.total_count')
150+
151+
if [ "${num_issues}" = "1" ]; then
152+
# Post a comment on the issue:
153+
comment="wave: Hi there! :wave:
154+
155+
And thank you for opening your first issue! We will get back to you shortly. :runner: :dash:"
156+
if ! github_api "POST" "/repos/${repo_owner}/${repo_name}/issues/${issue_number}/comments" "{\"body\":$(echo "${comment}" | jq -R -s -c .)}"; then
157+
echo "Failed to post comment on issue."
158+
on_error 1
159+
fi
160+
else
161+
echo "Issue is not the first contribution from the respective user."
162+
fi
163+
fi
164+
165+
print_success
166+
exit 0
167+
}
168+
169+
main

0 commit comments

Comments
 (0)