Skip to content

Commit 9b5ff78

Browse files
committed
Add Library Registry access control system
Background ---------- The Arduino Library Manager Registry repository receives thousands of pull requests from a large number of community contributors. The great majority of these contributors behave in a responsible manner. Unfortunately this repository is regularly the subject of irresponsible behavior. The small number of people who behave irresponsibly consume a significant amount of the finite maintenance resources available for maintenance of Arduino's repositories. Communication is always the first measure taken in these cases. This is done automatically by the "Manage PRs" workflow, and then by the registry maintainer when it becomes clear that the user has disregarded the comments from the bot. Unfortunately it is regularly the case that the user simply disregards all communication and continues their pattern of irresponsible behavior unchecked. Alternatives ------------ GitHub provides tools for dealing with harmful behavior: - Report user - Block user Reporting a user is the appropriate measure in cases of malicious behavior, and the account is usually banned from the site relatively quickly after a legitimate report is made. However, the irresponsible behavior in the registry repository is not overtly malicious and so reporting the user in these cases would not be appropriate or effective. At first glance, the block feature seems ideal. However, it can only be done at an organization-wide level, and by an organization administrator. The repository maintainer is not an organization administrator, so this makes the feature inconvenient to use. There is no sign of these users interacting with other repositories in the `arduino` organization, and so there is no benefit to blocking them at organization scope. In addition, in order to make it more difficult to circumvent the access restriction, we need the ability to block requests for libraries owned by an entity who has established a pattern of irresponsible behavior, regardless of which user submits the request. So the tools provided by GitHub are not suitable and a bespoke system must be implemented. Access Levels ------------- Allow: the user may submit requests for any library, even if registry privileges have been revoked for the owner of the library's repository. This access level will only be granted to registry maintainers, in order to allow them to make exceptions for specific libraries owned by an entity whose privileges have been revoked. Default: the user may submit requests for any library, unless registry privileges have been revoked for the owner of the library's repository. Deny: the user may not submit requests. Requests from users with "default" access level for any library repository owned by the entity (user or organization) are denied. In cases where a request is declined due to revocation of Library Manager Registry privileges, the "Manage PRs" workflow will automatically make an explanatory comment, including a link that provides more details about the cause of the revocation. It will also close the PR in the case where it is not possible for the requester to resolve the problem: * The requester's Library Manager Registry privileges have been revoked **-OR-** * The owners of all library repositories which are the subject of the request have lost Library Manager Registry privileges.
1 parent b234786 commit 9b5ff78

File tree

4 files changed

+146
-3
lines changed

4 files changed

+146
-3
lines changed

.github/CONTRIBUTING.md

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Contributor Guide
2+
3+
Thanks for your interest in contributing to the **Arduino Library Manager Registry**!
4+
5+
## Support and Discussion
6+
7+
If you would like to request assistance or discuss the **Library Manager Registry**, please make a topic on **Arduino Forum**:
8+
9+
https://forum.arduino.cc/c/17
10+
11+
## Registration and Maintenance
12+
13+
---
14+
15+
⚠ If you behave irresponsibly in your interactions with this repository, your Library Manager Registry privileges will be revoked.
16+
17+
Carefully read and follow the instructions in any comments the bot and human maintainers make on your pull requests. If you are having trouble following the instructions, add a comment that provides a detailed description of the problem you are having and a human maintainer will provide assistance.
18+
19+
Although we have set up automation for the most basic tasks, this repository is maintained by humans. So behave in a manner appropriate for interacting with humans, including clearly communicating what you are hoping to accomplish.
20+
21+
---
22+
23+
If you would like to submit a library, or request registry maintenance for a library already in the registry, please follow the instructions provided in the documentation:
24+
25+
[**Click here to see the documentation**](../README.md#table-of-contents)
26+
27+
Make sure to read the relevant sections of the FAQ:
28+
29+
[**Click here to see the FAQ**](../FAQ.md#table-of-contents)

.github/workflows/manage-prs.yml

+105-3
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ jobs:
125125
runs-on: ubuntu-latest
126126

127127
outputs:
128+
conclusion: ${{ steps.parse-request.outputs.conclusion }}
128129
type: ${{ steps.parse-request.outputs.type }}
129130
error: ${{ steps.parse-request.outputs.error }}
130131
arduinoLintLibraryManagerSetting: ${{ steps.parse-request.outputs.arduinoLintLibraryManagerSetting }}
@@ -170,6 +171,7 @@ jobs:
170171
)"
171172
# Due to limitations of the GitHub Actions workflow system, dedicated outputs must be created for use in
172173
# certain workflow fields.
174+
echo "::set-output name=conclusion::$(echo "$REQUEST" | jq -r -c '.conclusion')"
173175
echo "::set-output name=type::$(echo "$REQUEST" | jq -r -c '.type')"
174176
echo "::set-output name=error::$(echo "$REQUEST" | jq -r -c '.error')"
175177
echo "::set-output name=arduinoLintLibraryManagerSetting::$(echo "$REQUEST" | jq -r -c '.arduinoLintLibraryManagerSetting')"
@@ -195,10 +197,13 @@ jobs:
195197
labels: |
196198
- "topic: ${{ needs.parse.outputs.type }}"
197199
200+
# Handle problem found by the parser that can potentially be resolved by requester.
198201
parse-fail:
199202
needs:
200203
- parse
201-
if: needs.parse.outputs.error != ''
204+
if: >
205+
needs.parse.outputs.conclusion != 'declined' &&
206+
needs.parse.outputs.error != ''
202207
203208
runs-on: ubuntu-latest
204209
steps:
@@ -223,13 +228,64 @@ jobs:
223228
More information:
224229
https://github.com/${{ github.repository }}/blob/main/README.md#if-the-problem-is-with-the-pull-request
225230
231+
# Requester's registry privileges have been revoked.
232+
decline-request:
233+
needs:
234+
- parse
235+
if: >
236+
needs.parse.outputs.conclusion == 'declined' &&
237+
needs.parse.outputs.error != ''
238+
runs-on: ubuntu-latest
239+
steps:
240+
- name: Comment reason for declining request
241+
uses: octokit/request-action@v2.x
242+
if: needs.parse.outputs.error != ''
243+
env:
244+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
245+
with:
246+
route: POST /repos/{owner}/{repo}/issues/{issue_number}/comments
247+
owner: ${{ github.repository_owner }}
248+
repo: ${{ github.event.repository.name }}
249+
issue_number: ${{ github.event.pull_request.number }}${{ github.event.issue.number }}
250+
body: |
251+
|
252+
Hi @${{ github.actor }}
253+
Your request has been declined:
254+
255+
${{ env.ERROR_MESSAGE_PREFIX }}${{ needs.parse.outputs.error }}
256+
257+
- name: Close PR
258+
uses: octokit/request-action@v2.x
259+
env:
260+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
261+
with:
262+
route: PATCH /repos/{owner}/{repo}/pulls/{pull_number}
263+
owner: ${{ github.repository_owner }}
264+
repo: ${{ github.event.repository.name }}
265+
pull_number: ${{ github.event.pull_request.number }}${{ github.event.issue.number }}
266+
state: closed
267+
268+
- name: Add conclusion label to PR
269+
uses: octokit/request-action@v2.x
270+
env:
271+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
272+
with:
273+
# See: https://docs.github.com/rest/issues/labels#add-labels-to-an-issue
274+
route: POST /repos/{owner}/{repo}/issues/{issue_number}/labels
275+
owner: ${{ github.repository_owner }}
276+
repo: ${{ github.event.repository.name }}
277+
issue_number: ${{ github.event.pull_request.number }}${{ github.event.issue.number }}
278+
labels: |
279+
- "conclusion: ${{ needs.parse.outputs.conclusion }}"
280+
226281
check-submissions:
227282
name: Check ${{ matrix.submission.submissionURL }}
228283
needs:
229284
- parse
230285
if: >
231286
needs.parse.outputs.type == 'submission' ||
232287
needs.parse.outputs.type == 'modification'
288+
233289
runs-on: ubuntu-latest
234290
strategy:
235291
fail-fast: false
@@ -279,6 +335,15 @@ jobs:
279335
if: matrix.submission.error != ''
280336
run: echo "PASS=false" >> "$GITHUB_ENV"
281337

338+
# Parser checks are relevant in the case where request is declined due to registry access having been revoked for
339+
# the library repository owners. However, the rest of the checks are irrelevant and may result in confusing
340+
# comments from the bot, so should be skipped.
341+
- name: Skip the rest of the checks if request is declined
342+
if: >
343+
needs.parse.outputs.conclusion == 'declined' &&
344+
env.PASS == 'true'
345+
run: echo "PASS=false" >> "$GITHUB_ENV"
346+
282347
- name: Install Arduino Lint
283348
if: env.PASS == 'true'
284349
run: |
@@ -422,12 +487,15 @@ jobs:
422487
run: |
423488
test -d "${{ env.CHECK_SUBMISSIONS_FAIL_FLAG_ARTIFACT_PATH }}"
424489
490+
# Handle problem found by the submission checks that can potentially be resolved by requester.
425491
check-submissions-fail:
426492
needs:
493+
- parse
427494
- check-submissions-result
428-
if: needs.check-submissions-result.outputs.pass == 'false'
495+
if: >
496+
needs.parse.outputs.conclusion != 'declined' &&
497+
needs.check-submissions-result.outputs.pass == 'false'
429498
runs-on: ubuntu-latest
430-
431499
steps:
432500
- name: Comment instructions to fix errors detected during submission checks
433501
uses: octokit/request-action@v2.x
@@ -453,6 +521,37 @@ jobs:
453521
More information:
454522
https://github.com/${{ github.repository }}/blob/main/README.md#if-the-problem-is-with-the-pull-request
455523
524+
decline-submissions:
525+
needs:
526+
- parse
527+
- check-submissions
528+
if: needs.parse.outputs.conclusion == 'declined'
529+
runs-on: ubuntu-latest
530+
steps:
531+
- name: Close PR
532+
uses: octokit/request-action@v2.x
533+
env:
534+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
535+
with:
536+
route: PATCH /repos/{owner}/{repo}/pulls/{pull_number}
537+
owner: ${{ github.repository_owner }}
538+
repo: ${{ github.event.repository.name }}
539+
pull_number: ${{ github.event.pull_request.number }}${{ github.event.issue.number }}
540+
state: closed
541+
542+
- name: Add conclusion label to PR
543+
uses: octokit/request-action@v2.x
544+
env:
545+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
546+
with:
547+
# See: https://docs.github.com/rest/issues/labels#add-labels-to-an-issue
548+
route: POST /repos/{owner}/{repo}/issues/{issue_number}/labels
549+
owner: ${{ github.repository_owner }}
550+
repo: ${{ github.event.repository.name }}
551+
issue_number: ${{ github.event.pull_request.number }}${{ github.event.issue.number }}
552+
labels: |
553+
- "conclusion: ${{ needs.parse.outputs.conclusion }}"
554+
456555
merge:
457556
needs:
458557
- diff
@@ -605,6 +704,7 @@ jobs:
605704
- parse
606705
# These request types can't be automatically approved.
607706
if: >
707+
needs.parse.outputs.conclusion != 'declined' &&
608708
needs.parse.outputs.type != 'submission' &&
609709
needs.parse.outputs.type != 'invalid'
610710
runs-on: ubuntu-latest
@@ -631,8 +731,10 @@ jobs:
631731
needs:
632732
# Run after all other jobs
633733
- parse-fail
734+
- decline-request
634735
- merge-fail
635736
- check-submissions-fail
737+
- decline-submissions
636738
- label
637739
- not-submission
638740
# Run if any job failed. The workflow is configured so that jobs only fail when there is an unexpected error.

FAQ.md

+2
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ Follow the instructions [here](README.md#adding-a-library-to-library-manager).
7272

7373
### What are the requirements for a library to be added to Library Manager?
7474

75+
- [ ] The library must be something of potential value to the Arduino community.
76+
- [ ] The submitter must behave in a responsible manner in their interactions with the Library Manager Registry.
7577
- [ ] The library must be fully compliant with the [Arduino Library Specification](https://arduino.github.io/arduino-cli/latest/library-specification).
7678
- [ ] The library must have [a library.properties file](https://arduino.github.io/arduino-cli/latest/library-specification/#library-metadata), in compliance with the Arduino Library 1.5 format.
7779
- [ ] The library.properties file must be located in the root of the repository.

README.md

+10
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ See the instructions below for detailed instructions on how to do this via the G
3333

3434
### Instructions
3535

36+
---
37+
38+
⚠ If you behave irresponsibly in your interactions with this repository, your Library Manager Registry privileges will be revoked.
39+
40+
Carefully read and follow the instructions in any comments the bot and human maintainers make on your pull requests. If you are having trouble following the instructions, add a comment that provides a detailed description of the problem you are having and a human maintainer will provide assistance.
41+
42+
Although we have set up automation for the most basic tasks, this repository is maintained by humans. So behave in a manner appropriate for interacting with humans, including clearly communicating what you are hoping to accomplish.
43+
44+
---
45+
3646
1. You may want to first take a look at
3747
[the requirements for admission into the Arduino Library Manager index](FAQ.md#submission-requirements). Each submission will be checked for
3848
compliance before being accepted.

0 commit comments

Comments
 (0)