Issues #129
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Issues | |
on: | |
issues: | |
types: [opened] | |
issue_comment: | |
types: [created, edited] | |
schedule: | |
- cron: "0 9 * * *" # Every day at 9am UTC. | |
workflow_dispatch: | |
workflow_call: | |
secrets: | |
CFL_BOT_GH_TOKEN: | |
description: "The CFL-bot's GitHub token. Used to comment." | |
required: false | |
jobs: | |
opened: | |
runs-on: ubuntu-22.04 | |
if: | | |
github.repository_owner_id == 2088731 && | |
github.event_name == 'issues' && | |
github.event.action == 'opened' && | |
github.event.issue.user.login != 'cfl-bot' && | |
!contains(github.event.issue.labels.*.name, 'bot ignore') | |
env: | |
GH_TOKEN: ${{ secrets.CFL_BOT_GH_TOKEN }} | |
steps: | |
- name: ✍️ Download and Write Was-Opened Comment | |
uses: ocadotechnology/codeforlife-workspace/.github/actions/bot/comment-on-issue@main | |
with: | |
download-issue-comment-path: was-opened.md | |
comment-created-or-edited: | |
runs-on: ubuntu-22.04 | |
if: | | |
github.repository_owner_id == 2088731 && | |
github.event_name == 'issue_comment' && | |
!github.event.issue.pull_request && | |
contains(fromJSON('["created", "edited"]'), github.event.action) && | |
github.event.comment.user.login != 'cfl-bot' && | |
!contains(github.event.issue.labels.*.name, 'bot ignore') | |
env: | |
GH_TOKEN: ${{ secrets.CFL_BOT_GH_TOKEN }} | |
# Prompts | |
ASSIGN_ME_PROMPT: "+" | |
UNASSIGN_ME_PROMPT: "-" | |
READY_FOR_REVIEW_PROMPT: "!" | |
READY_FOR_REVIEW_LABEL: "ready for review" | |
REQUIRES_CHANGES_PROMPT: "?" | |
# Common Conditions | |
COMMENTER_IS_ASSIGNED: ${{ contains(github.event.issue.assignees.*.id, github.event.comment.user.id) }} | |
IS_OPEN: ${{ github.event.issue.state == 'open' }} | |
steps: | |
- name: 🔍 Extract Prompt | |
id: _ # Shorthand | |
run: | | |
comment_body=$( | |
echo "${{ github.event.comment.body }}" | | |
sed --regexp-extended ' | |
s/(^|\W)@cfl-bot($|\W)/\1\2/g; | |
s/^[[:space:]]*|[[:space:]]*$//g; | |
s/[[:space:]]{2,}/ /g | |
' | | |
tr '[:upper:]' '[:lower:]' | |
) | |
comment_body_alpha=$(echo "$comment_body" | tr -dc '[:alpha:]') | |
comment_body_punct=$(echo "$comment_body" | tr -dc '[:punct:]') | |
prompt_aliases=( | |
"assign me=${{ env.ASSIGN_ME_PROMPT }}" | |
"unassign me=${{ env.UNASSIGN_ME_PROMPT }}" | |
"ready for review=${{ env.READY_FOR_REVIEW_PROMPT }}" | |
"requires changes=${{ env.REQUIRES_CHANGES_PROMPT }}" | |
) | |
prompt="" | |
for prompt_alias in "${prompt_aliases[@]}"; do | |
text="${prompt_alias%=*}" | |
symbol="${prompt_alias#*=}" | |
if [ "$comment_body_alpha" = "$text" ] || | |
[ "$comment_body_punct" = "$symbol" ]; then | |
prompt="$symbol" | |
break | |
fi | |
done | |
function set_output() { echo "$1=$2" >> $GITHUB_OUTPUT; } | |
set_output "prompt" "$prompt" | |
if [ -z "$prompt" ]; then exit 0; fi | |
if [ "$prompt" = "${{ env.ASSIGN_ME_PROMPT }}" ]; then | |
set_output "max-assignees" "${{ github.event.issue.assignees.length >= 5 }}" | |
fi | |
if [ "$prompt" = "${{ env.READY_FOR_REVIEW_PROMPT }}" ] || [ "$prompt" = "${{ env.REQUIRES_CHANGES_PROMPT }}" ]; then | |
set_output "has-label" "${{ contains(github.event.issue.labels.*.name, env.READY_FOR_REVIEW_LABEL) }}" | |
fi | |
# assign me | |
- name: "✍️ Assign Me: Download and Write Closed-State Comment" | |
id: assign-me-closed-state | |
if: | | |
steps._.outputs.prompt == env.ASSIGN_ME_PROMPT && | |
env.IS_OPEN == 'false' | |
uses: ocadotechnology/codeforlife-workspace/.github/actions/bot/comment-on-issue@main | |
with: | |
download-issue-comment-path: prompts/assign-me/closed-state.md | |
write-substitutions: | | |
contributor=@${{ github.event.comment.user.login }} | |
- name: "✍️ Assign Me: Download and Write Already-Assigned Comment" | |
id: assign-me-already-assigned | |
if: | | |
steps._.outputs.prompt == env.ASSIGN_ME_PROMPT && | |
env.IS_OPEN == 'true' && | |
env.COMMENTER_IS_ASSIGNED == 'true' | |
uses: ocadotechnology/codeforlife-workspace/.github/actions/bot/comment-on-issue@main | |
with: | |
download-issue-comment-path: prompts/assign-me/already-assigned.md | |
write-substitutions: | | |
contributor=@${{ github.event.comment.user.login }} | |
- name: "✍️ Assign Me: Download and Write Max-Assignees Comment" | |
id: assign-me-max-assignees | |
if: | | |
steps._.outputs.prompt == env.ASSIGN_ME_PROMPT && | |
env.IS_OPEN == 'true' && | |
env.COMMENTER_IS_ASSIGNED == 'false' && | |
steps._.outputs.max-assignees == 'true' | |
uses: ocadotechnology/codeforlife-workspace/.github/actions/bot/comment-on-issue@main | |
with: | |
download-issue-comment-path: prompts/assign-me/max-assignees.md | |
write-substitutions: | | |
contributor=@${{ github.event.comment.user.login }} | |
- name: "🏃 Assign Me: Run" | |
if: | | |
steps._.outputs.prompt == env.ASSIGN_ME_PROMPT && | |
steps.assign-me-already-assigned.conclusion == 'skipped' && | |
steps.assign-me-closed-state.conclusion == 'skipped' && | |
steps.assign-me-max-assignees.conclusion == 'skipped' | |
run: | | |
gh api graphql -f query=' | |
mutation { | |
addAssignee: addAssigneesToAssignable(input: { | |
assignableId: "${{ github.event.issue.node_id }}" | |
assigneeIds: ["${{ github.event.comment.user.node_id }}"] | |
}) { | |
assignable { ... on Issue { id } } | |
} | |
}' | |
# unassign me | |
- name: "✍️ Unassign Me: Download and Write Not-Assigned Comment" | |
id: unassign-me-not-assigned | |
if: | | |
steps._.outputs.prompt == env.UNASSIGN_ME_PROMPT && | |
env.COMMENTER_IS_ASSIGNED == 'false' | |
uses: ocadotechnology/codeforlife-workspace/.github/actions/bot/comment-on-issue@main | |
with: | |
download-issue-comment-path: prompts/unassign-me/not-assigned.md | |
write-substitutions: | | |
contributor=@${{ github.event.comment.user.login }} | |
- name: "🏃 Unassign Me: Run" | |
if: | | |
steps._.outputs.prompt == env.UNASSIGN_ME_PROMPT && | |
steps.unassign-me-not-assigned.conclusion == 'skipped' | |
run: | | |
gh api graphql -f query=' | |
mutation { | |
removeAssignee: removeAssigneesFromAssignable(input: { | |
assignableId: "${{ github.event.issue.node_id }}" | |
assigneeIds: ["${{ github.event.comment.user.node_id }}"] | |
}) { | |
assignable { ... on Issue { id } } | |
} | |
}' | |
# ready for review | |
- name: "✍️ Ready for Review: Download and Write Closed-State Comment" | |
id: ready-for-review-closed-state | |
if: | | |
steps._.outputs.prompt == env.READY_FOR_REVIEW_PROMPT && | |
env.IS_OPEN == 'false' | |
uses: ocadotechnology/codeforlife-workspace/.github/actions/bot/comment-on-issue@main | |
with: | |
download-issue-comment-path: prompts/ready-for-review/closed-state.md | |
write-substitutions: | | |
contributor=@${{ github.event.comment.user.login }} | |
- name: "✍️ Ready for Review: Download and Write Not-Assigned Comment" | |
id: ready-for-review-not-assigned | |
if: | | |
steps._.outputs.prompt == env.READY_FOR_REVIEW_PROMPT && | |
env.IS_OPEN == 'true' && | |
env.COMMENTER_IS_ASSIGNED == 'false' | |
uses: ocadotechnology/codeforlife-workspace/.github/actions/bot/comment-on-issue@main | |
with: | |
download-issue-comment-path: prompts/ready-for-review/not-assigned.md | |
write-substitutions: | | |
contributor=@${{ github.event.comment.user.login }} | |
- name: "✍️ Ready for Review: Download and Write Already-Labelled Comment" | |
id: ready-for-review-already-labelled | |
if: | | |
steps._.outputs.prompt == env.READY_FOR_REVIEW_PROMPT && | |
env.IS_OPEN == 'true' && | |
env.COMMENTER_IS_ASSIGNED == 'true' && | |
steps._.outputs.has-label == 'true' | |
uses: ocadotechnology/codeforlife-workspace/.github/actions/bot/comment-on-issue@main | |
with: | |
download-issue-comment-path: prompts/ready-for-review/already-labelled.md | |
write-substitutions: | | |
contributor=@${{ github.event.comment.user.login }} | |
- name: "🏃 Ready for Review: Run" | |
if: | | |
steps._.outputs.prompt == env.READY_FOR_REVIEW_PROMPT && | |
steps.ready-for-review-closed-state.conclusion == 'skipped' && | |
steps.ready-for-review-not-assigned.conclusion == 'skipped' && | |
steps.ready-for-review-already-labelled.conclusion == 'skipped' | |
run: | | |
gh label create "${{ env.READY_FOR_REVIEW_PROMPT }}" \ | |
--repo=${{ github.repository }} \ | |
--force \ | |
--color="#fbca04" \ | |
--description="This issue is awaiting review by a CFL team member." | |
gh issue edit ${{ github.event.issue.number }} \ | |
--repo=${{ github.repository }} \ | |
--add-label="${{ env.READY_FOR_REVIEW_LABEL }}" | |
# requires changes | |
- name: "✍️ Requires Changes: Download and Write Closed-State Comment" | |
id: requires-changes-closed-state | |
if: | | |
steps._.outputs.prompt == env.REQUIRES_CHANGES_PROMPT && | |
env.IS_OPEN == 'false' | |
uses: ocadotechnology/codeforlife-workspace/.github/actions/bot/comment-on-issue@main | |
with: | |
download-issue-comment-path: prompts/requires-changes/closed-state.md | |
write-substitutions: | | |
contributor=@${{ github.event.comment.user.login }} | |
- name: "✍️ Requires Changes: Download and Write Not-Assigned Comment" | |
id: requires-changes-not-assigned | |
if: | | |
steps._.outputs.prompt == env.REQUIRES_CHANGES_PROMPT && | |
env.IS_OPEN == 'true' && | |
env.COMMENTER_IS_ASSIGNED == 'false' | |
uses: ocadotechnology/codeforlife-workspace/.github/actions/bot/comment-on-issue@main | |
with: | |
download-issue-comment-path: prompts/requires-changes/not-assigned.md | |
write-substitutions: | | |
contributor=@${{ github.event.comment.user.login }} | |
- name: "✍️ Requires Changes: Download and Write Not-Labelled Comment" | |
id: requires-changes-not-labelled | |
if: | | |
steps._.outputs.prompt == env.REQUIRES_CHANGES_PROMPT && | |
env.IS_OPEN == 'true' && | |
env.COMMENTER_IS_ASSIGNED == 'true' && | |
steps._.outputs.has-label == 'false' | |
uses: ocadotechnology/codeforlife-workspace/.github/actions/bot/comment-on-issue@main | |
with: | |
download-issue-comment-path: prompts/requires-changes/not-labelled.md | |
write-substitutions: | | |
contributor=@${{ github.event.comment.user.login }} | |
- name: "🏃 Requires Changes: Run" | |
if: | | |
steps._.outputs.prompt == env.REQUIRES_CHANGES_PROMPT && | |
steps.requires-changes-closed-state.conclusion == 'skipped' && | |
steps.requires-changes-not-assigned.conclusion == 'skipped' && | |
steps.requires-changes-not-labelled.conclusion == 'skipped' | |
run: | | |
gh issue edit ${{ github.event.issue.number }} \ | |
--repo=${{ github.repository }} \ | |
--remove-label="${{ env.READY_FOR_REVIEW_LABEL }}" | |
inactive: | |
runs-on: ubuntu-22.04 | |
if: | | |
github.repository_owner_id == 2088731 && | |
contains(fromJSON('["schedule", "workflow_dispatch"]'), github.event_name) | |
env: | |
GH_TOKEN: ${{ secrets.CFL_BOT_GH_TOKEN }} | |
ONE_WEEK_MD: 1-week.md | |
TWO_WEEKS_MD: 2-weeks.md | |
THREE_WEEKS_MD: 3-weeks.md | |
SCRIPT: process.sh | |
steps: | |
- name: 📥 Download 1-Week Comment | |
uses: ocadotechnology/codeforlife-workspace/.github/actions/workspace/download-file@main | |
with: | |
path: .github/comments/issue/inactive/1-week.md | |
save-to: ${{ env.ONE_WEEK_MD }} | |
- name: 📥 Download 2-Weeks Comment | |
uses: ocadotechnology/codeforlife-workspace/.github/actions/workspace/download-file@main | |
with: | |
path: .github/comments/issue/inactive/2-weeks.md | |
save-to: ${{ env.TWO_WEEKS_MD }} | |
- name: 📥 Download 3-Weeks Comment | |
uses: ocadotechnology/codeforlife-workspace/.github/actions/workspace/download-file@main | |
with: | |
path: .github/comments/issue/inactive/3-weeks.md | |
save-to: ${{ env.THREE_WEEKS_MD }} | |
- name: 📥 Download Script | |
uses: ocadotechnology/codeforlife-workspace/.github/actions/workspace/download-file@main | |
with: | |
path: .github/scripts/unassign_inactive_issue_assignees.sh | |
save-to: ${{ env.SCRIPT }} | |
type: bash | |
- name: ⚙️ Unassign Inactive Contributors | |
uses: ocadotechnology/codeforlife-workspace/.github/actions/workspace/process-submodules@main | |
with: | |
pre-processing: process "${{ github.event.repository.name }}" | |
process: source ${{ env.SCRIPT }} |