From cfd19178589201fdd26c1e7862870352fa60a20a Mon Sep 17 00:00:00 2001 From: Philipp Burckhardt Date: Thu, 6 Mar 2025 09:58:06 -0500 Subject: [PATCH 1/4] 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 --- --- .github/workflows/first_time_greeting.yml | 17 +- .github/workflows/scripts/first_time_greeting | 169 ++++++++++++++++++ 2 files changed, 174 insertions(+), 12 deletions(-) create mode 100755 .github/workflows/scripts/first_time_greeting diff --git a/.github/workflows/first_time_greeting.yml b/.github/workflows/first_time_greeting.yml index 1eb5acae18f8..a25eee93145e 100644 --- a/.github/workflows/first_time_greeting.yml +++ b/.github/workflows/first_time_greeting.yml @@ -44,15 +44,8 @@ jobs: # Greet first-time contributors: - name: 'Greet first-time contributors' - # Pin action to full length commit SHA - uses: actions/first-interaction@34f15e814fe48ac9312ccf29db4e74fa767cbab7 # v1.3.0 - with: - repo-token: ${{ secrets.STDLIB_BOT_PAT_REPO_WRITE }} - issue-message: | - :wave: Hi there! :wave: - - And thank you for opening your first issue! We will get back to you shortly. :runner: :dash: - pr-message: | - :wave: Hi there! :wave: - - And thank you for opening your first pull request! We will review it shortly. :runner: :dash: + env: + ISSUE_NUMBER: ${{ github.event.issue.number }} + GITHUB_TOKEN: ${{ secrets.STDLIB_BOT_PAT_REPO_WRITE }} + run: | + . "$GITHUB_WORKSPACE/.github/workflows/scripts/first_time_greeting" $ISSUE_NUMBER diff --git a/.github/workflows/scripts/first_time_greeting b/.github/workflows/scripts/first_time_greeting new file mode 100755 index 000000000000..eb74a05f25fc --- /dev/null +++ b/.github/workflows/scripts/first_time_greeting @@ -0,0 +1,169 @@ +#!/usr/bin/env bash +# +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Script to greet first-time contributors. +# +# Usage: first_time_greeting +# +# Arguments: +# +# issue_number Issue or pull request number. +# +# Environment variables: +# +# GITHUB_TOKEN GitHub token for authentication. + +# Ensure that the exit status of pipelines is non-zero in the event that at least one of the commands in a pipeline fails: +set -o pipefail + + +# VARIABLES # + +# Resolve the issue or pull request number: +issue_number="$1" + +# GitHub API base URL: +github_api_url="https://api.github.com" + +# Repository owner and name: +repo_owner="stdlib-js" +repo_name="stdlib" + + +# FUNCTIONS # + +# Error handler. +# +# $1 - error status +on_error() { + echo 'ERROR: An error was encountered during execution.' >&2 + exit "$1" +} + +# Prints a success message. +print_success() { + echo 'Success!' >&2 +} + +# Performs a GitHub API request. +# +# $1 - HTTP method (GET or POST) +# $2 - API endpoint +# $3 - data for POST requests +github_api() { + local method="$1" + local endpoint="$2" + local data="$3" + + # Initialize an array to hold curl headers: + local headers=() + + # If GITHUB_TOKEN is set, add the Authorization header: + if [ -n "${GITHUB_TOKEN}" ]; then + headers+=("-H" "Authorization: token ${GITHUB_TOKEN}") + fi + + # Determine the HTTP method and construct the curl command accordingly... + case "${method}" in + GET) + curl -s "${headers[@]}" "${github_api_url}${endpoint}" + ;; + POST) + # For POST requests, always set the Content-Type header: + headers+=("-H" "Content-Type: application/json") + + # If data is provided, include it in the request: + if [ -n "${data}" ]; then + curl -s -X POST "${headers[@]}" -d "${data}" "${github_api_url}${endpoint}" + else + # Handle cases where POST data is required but not provided: + echo "ERROR: POST request requires data." + on_error 1 + fi + ;; + *) + echo "ERROR: Invalid HTTP method: ${method}." + on_error 1 + ;; + esac +} + +# Main execution sequence. +main() { + local user_issues + local user_login + local user_prs + local details + local is_pr + + if [ -z "${issue_number}" ]; then + echo "ERROR: Issue or pull request number is required." >&2 + on_error 1 + fi + + # Fetch details: + details=$(github_api "GET" "/repos/${repo_owner}/${repo_name}/issues/${issue_number}") + user_login=$(echo "${details}" | jq -r '.user.login') + + is_pr=$(echo "$details" | jq -r 'has("pull_request")') + + if [ "${is_pr}" = "true" ]; then + # Fetch PRs opened by the user: + user_prs=$(github_api "GET" "/search/issues?q=repo%3A${repo_owner}%2F${repo_name}+author%3A${user_login}+type%3Apr") + + # Extract number of PRs by the user: + num_prs=$(echo "${user_prs}" | jq -r '.total_count') + + if [ "${num_prs}" = "1" ]; then + # Post a comment on the PR: + comment=":wave: Hi there! :wave: + + And thank you for opening your first pull request! We will review it shortly. :runner: :dash:" + if ! github_api "POST" "/repos/${repo_owner}/${repo_name}/issues/${issue_number}/comments" "{\"body\":$(echo "${comment}" | jq -R -s -c .)}"; then + echo "Failed to post comment on PR." + on_error 1 + fi + else + echo "PR is not the first contribution from the respective user." + fi + else + # Fetch issues opened by the user: + user_issues=$(github_api "GET" "/search/issues?q=repo%3A${repo_owner}%2F${repo_name}+author%3A${user_login}+type%3Aissue") + + # Extract number of issues by the user: + num_issues=$(echo "${user_issues}" | jq -r '.total_count') + + if [ "${num_issues}" = "1" ]; then + # Post a comment on the issue: + comment="wave: Hi there! :wave: + + And thank you for opening your first issue! We will get back to you shortly. :runner: :dash:" + if ! github_api "POST" "/repos/${repo_owner}/${repo_name}/issues/${issue_number}/comments" "{\"body\":$(echo "${comment}" | jq -R -s -c .)}"; then + echo "Failed to post comment on issue." + on_error 1 + fi + else + echo "Issue is not the first contribution from the respective user." + fi + fi + + print_success + exit 0 +} + +main From 7b6f35a61cb13a0ac3ad47bbf2885265378c7ac4 Mon Sep 17 00:00:00 2001 From: Philipp Burckhardt Date: Mon, 17 Mar 2025 20:03:20 -0400 Subject: [PATCH 2/4] build: add missing checkout step --- 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: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- .github/workflows/first_time_greeting.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/first_time_greeting.yml b/.github/workflows/first_time_greeting.yml index a25eee93145e..62f04e8b78e2 100644 --- a/.github/workflows/first_time_greeting.yml +++ b/.github/workflows/first_time_greeting.yml @@ -42,6 +42,17 @@ jobs: # Define the sequence of job steps... steps: + # Checkout the repository: + - name: 'Checkout repository' + # Pin action to full length commit SHA + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + # Ensure we have access to the scripts directory: + sparse-checkout: | + .github/workflows/scripts + sparse-checkout-cone-mode: false + timeout-minutes: 10 + # Greet first-time contributors: - name: 'Greet first-time contributors' env: From 44b0c1215391d0ad193f1f6c2f6457503ec8fc5b Mon Sep 17 00:00:00 2001 From: Philipp Burckhardt Date: Sat, 5 Apr 2025 14:36:58 -0400 Subject: [PATCH 3/4] build: expand first PR and first issue comments --- 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 --- --- .github/workflows/scripts/first_time_greeting | 54 ++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/.github/workflows/scripts/first_time_greeting b/.github/workflows/scripts/first_time_greeting index eb74a05f25fc..0ae9ea1649ec 100755 --- a/.github/workflows/scripts/first_time_greeting +++ b/.github/workflows/scripts/first_time_greeting @@ -133,7 +133,53 @@ main() { # Post a comment on the PR: comment=":wave: Hi there! :wave: - And thank you for opening your first pull request! We will review it shortly. :runner: :dash:" + And thank you for opening your first pull request! We will review it shortly. :runner: :dash: + + ## Getting Started + + - Please read our [contributing guidelines][stdlib-contributing] if you haven't already. + - For development guidance, refer to the [development guide][stdlib-development] + + ## Next Steps + + 1. A project maintainer will approve GitHub Actions workflows for your PR. + 2. All CI checks must pass before your submission can be fully reviewed. + 3. You'll need to address any failures in linting or unit tests. + + ## Running Tests Locally + + You can use \`make\` to run any of the CI commands locally from the **root directory** of the stdlib repository: + + \`\`\`bash + # Run tests for all packages in the math namespace: + make test TESTS_FILTER=\".*/@stdlib/math/.*\" + + # Run benchmarks for a specific package: + make benchmark BENCHMARKS_FILTER=\".*/@stdlib/math/base/special/sin/.*\" + \`\`\` + + If you haven't heard back from us within two weeks, please ping us by tagging the \"reviewers\" team in a comment on this PR. + + If you have any further questions while waiting for a response, please join our [Gitter channel][stdlib-gitter] to chat with project maintainers and other community members. + + We appreciate your contribution! + + ## Documentation Links + + - [Contributing Guidelines][stdlib-contributing] + - [Developtment Guide][stdlib-development] + - [Gitter channel][stdlib-gitter] + - [make rules for running examples][make-docs-examples] + - [make rules for running project unit tests][make-docs-test] + - [make rules for running benchmarks][make-docs-benchmark] + + [stdlib-contributing]: https://github.com/stdlib-js/stdlib/blob/develop/CONTRIBUTING.md + [stdlib-development]: https://github.com/stdlib-js/stdlib/blob/develop/docs/contributing/development.md + [stdlib-gitter]: https://gitter.im/stdlib-js/stdlib + + [make-docs-examples]: https://github.com/stdlib-js/stdlib/blob/develop/tools/make/lib/examples/README.md + [make-docs-test]: https://github.com/stdlib-js/stdlib/blob/develop/tools/make/lib/test/README.md + [make-docs-benchmark]: https://github.com/stdlib-js/stdlib/blob/develop/tools/make/lib/benchmark/README.md" if ! github_api "POST" "/repos/${repo_owner}/${repo_name}/issues/${issue_number}/comments" "{\"body\":$(echo "${comment}" | jq -R -s -c .)}"; then echo "Failed to post comment on PR." on_error 1 @@ -152,7 +198,11 @@ main() { # Post a comment on the issue: comment="wave: Hi there! :wave: - And thank you for opening your first issue! We will get back to you shortly. :runner: :dash:" + And thank you for opening your first issue! We will get back to you shortly. :runner: :dash: + + If you have any further questions while waiting for a response, please join our [Gitter channel][stdlib-gitter] to chat with project maintainers and other community members. + + [stdlib-gitter]: https://gitter.im/stdlib-js/stdlib" if ! github_api "POST" "/repos/${repo_owner}/${repo_name}/issues/${issue_number}/comments" "{\"body\":$(echo "${comment}" | jq -R -s -c .)}"; then echo "Failed to post comment on issue." on_error 1 From e89ba591601806acbb8c057fdb7d7ef409bced94 Mon Sep 17 00:00:00 2001 From: Athan Date: Wed, 9 Apr 2025 01:08:47 -0700 Subject: [PATCH 4/4] Apply suggestions from code review Signed-off-by: Athan --- .github/workflows/scripts/first_time_greeting | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/scripts/first_time_greeting b/.github/workflows/scripts/first_time_greeting index 0ae9ea1649ec..90d8d0fc3aec 100755 --- a/.github/workflows/scripts/first_time_greeting +++ b/.github/workflows/scripts/first_time_greeting @@ -138,7 +138,7 @@ main() { ## Getting Started - Please read our [contributing guidelines][stdlib-contributing] if you haven't already. - - For development guidance, refer to the [development guide][stdlib-development] + - For development guidance, refer to the [development guide][stdlib-development]. ## Next Steps @@ -170,7 +170,7 @@ main() { - [Developtment Guide][stdlib-development] - [Gitter channel][stdlib-gitter] - [make rules for running examples][make-docs-examples] - - [make rules for running project unit tests][make-docs-test] + - [make rules for running unit tests][make-docs-test] - [make rules for running benchmarks][make-docs-benchmark] [stdlib-contributing]: https://github.com/stdlib-js/stdlib/blob/develop/CONTRIBUTING.md