diff --git a/.github/PULL_REQUEST_TEMPLATE/advance-to-ready-for-release.md b/.github/PULL_REQUEST_TEMPLATE/advance-to-ready-for-release.md new file mode 100644 index 0000000000..659a59100d --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/advance-to-ready-for-release.md @@ -0,0 +1,52 @@ +# Advance #__RFC_NUMBER__ to the [Ready For Release Stage](https://github.com/emberjs/rfcs#ready-for-release) + +## Summary + +This pull request is advancing the RFC to the [Ready For Release Stage](https://github.com/emberjs/rfcs#ready-for-release). + +- PR to Accepted Stage: #__RFC_NUMBER__ + +**An FCP is required before merging this PR to advance.** + +Upon merging this PR, automation will open a draft PR for this RFC to move to the [Released Stage](https://github.com/emberjs/rfcs#released). + +
+ Ready for Release Stage Description + +This stage is complete when the implementation is complete according to plan outlined in the RFC, and is in harmony with any changes in Ember that have occurred since the RFC was first written. This includes any necessary learning materials. At this stage, features or deprecations may be available for use behind a feature flag, or with an optional package, etc. + +For codebase changes, there are no open questions that are anticipated to require breaking changes; the Ember team is ready to commit to the stability of any interfaces exposed by the current implementation of the feature. + +This stage should include a list of criteria for determining when the proposal can be considered Recommended after being Released. + +An FCP is required to move into this stage. + +Each Ember core team will be requested as a reviewer on the PR to move into this stage. A representative of each team adds a review. If a team does not respond to the request, and after the conclusion of the FCP, it is assumed that the release may proceed. +
+ +## Checklist to move to Ready for Release + +- [ ] Implementation is complete according to plan outlined in the RFC, with any adjustments noted in the RFC +- [ ] Any necessary learning materials have been updated +- [ ] The Ember team is ready to commit to the stability of any interfaces exposed by the current implementation of the feature +- [ ] Criteria for moving to the Recommended Stage has been filled out +- [ ] This PR has been converted from a draft to a regular PR and the `Final Comment Period` label has been added to start the FCP +- [ ] Each [team](https://github.com/emberjs/rfcs#relevant-teams) has been added as a reviewer to the PR at the start of the FCP + * [ ] Framework @emberjs/framework + * [ ] Data @emberjs/ember-data-core + * [ ] CLI @emberjs/cli + * [ ] Learning @emberjs/learning-core + * [ ] Typescript @emberjs/typescript-core + * [ ] Steering @emberjs/steering + + +## Criteria for moving to Recommended (required) + +A set of criteria for moving this RFC to the Recommended Stage, following release: + +1. +2. + +## Track Implementation + +<-- Use this section to track implementation of the RFC --> diff --git a/.github/PULL_REQUEST_TEMPLATE/advance-to-recommended.md b/.github/PULL_REQUEST_TEMPLATE/advance-to-recommended.md new file mode 100644 index 0000000000..0c2bb48b9e --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/advance-to-recommended.md @@ -0,0 +1,53 @@ +# Advance #__RFC_NUMBER__ to the [Recommended Stage](https://github.com/emberjs/rfcs#recommended) + +## Summary + +This pull request is advancing the RFC to the [Recommended Stage](https://github.com/emberjs/rfcs#recommended). + +- PR to Accepted Stage: #__RFC_NUMBER__ +- [PR to Ready For Release Stage](__READY_FOR_RELEASE_PR__) +- [PR to Released Stage](__RELEASED_PR__) + +**An FCP is required before merging this PR to advance.** + + +
+Recommended Stage Summary + +The "Recommended" stage is the final milestone for an RFC. It provides a signal to the wider community to indicate that a feature has been put through its ecosystem paces and is ready to use. + +To reach the "Recommended" stage, the following should be true: + +If appropriate, the feature is integrated into the tutorial and the guides prose. API documentation is polished and updates are carried through to other areas of API docs that may not directly pertain to the feature. + +If the proposal replaces an existing feature, the addon ecosystem has largely updated to work with both old and new features. + +If the proposal updates or replaces an existing feature, high-quality codemods are available. + +If needed, Ember debugging tools as well as popular IDE support have been updated to support the feature. + +If the feature is part of a suite of features that were designed to work together for best ergonomics, the other features are also ready to be "Recommended". + +Any criteria for "Recommended" for this proposal that were established in the Ready For Release stage have been met. + +An FCP is required to enter this stage. Multiple RFCs may be moved as a batch into "Recommended" with the same PR. +
+ +## Checklist to move to Recommended + +- [ ] Any criteria for "Recommended" for this proposal that were established in the Ready For Release stage have been met +- [ ] If appropriate, the feature is integrated into the tutorial and the guides prose. API documentation is polished and updates are carried through to other areas of API docs that may not directly pertain to the feature. +- [ ] If the proposal replaces an existing feature, the addon ecosystem has largely updated to work with both old and new features. +- [ ] If the proposal updates or replaces an existing feature, high-quality codemods are available +- [ ] If needed, Ember debugging tools as well as popular IDE support have been updated to support the feature. +- [ ] If the feature is part of a suite of features that were designed to work together for best ergonomics, the other features are also ready to be "Recommended". +- [ ] This PR has been converted from a draft to a regular PR and the `Final Comment Period` label has been added to start the FCP + +## Criteria for moving to Recommended (required) + +<-- Copy and paste the criteria for "Recommended" from the Ready For Release stage here --> + +A set of criteria for moving this RFC to the Recommended Stage, following release: + +1. +2. diff --git a/.github/PULL_REQUEST_TEMPLATE/advance-to-released.md b/.github/PULL_REQUEST_TEMPLATE/advance-to-released.md new file mode 100644 index 0000000000..494411a73e --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/advance-to-released.md @@ -0,0 +1,28 @@ +# Advance #__RFC_NUMBER__ to the [Released Stage](https://github.com/emberjs/rfcs#released) + +## Summary + +This pull request is advancing the RFC to the [Released Stage](https://github.com/emberjs/rfcs#released). + +- PR to Accepted Stage: #__RFC_NUMBER__ +- [PR to Ready For Release Stage](__READY_FOR_RELEASE_PR__) + +Upon merging this PR, automation will open a draft PR for this RFC to move to the [Recommended Stage](https://github.com/emberjs/rfcs#recommended). + +
+Released Stage Summary + +The work is published. If it is codebase-related work, it is in a stable version of the relevant package(s). If there are any critical deviations from the original RFC, they are briefly noted at the top of the RFC. + +If the work for an RFC is spread across multiple releases of Ember or other packages, the RFC is considered to be in the Released stage when all features are available in stable releases and those packages and versions are noted in the RFC frontmatter. + +Ember's RFC process can be used for process and work plans that are not about code. Some examples include Roadmap RFCs, changes to the RFC process itself, and changes to learning resources. When such an RFC is a candidate for Released, the work should be shipped as described, and the result should presented to the team with the intent of gathering feedback about whether anything is missing. If there is agreement that the work is complete, the RFC may be marked "Released" and a date is provided instead of a version. + +An RFC is moved into "Released" when the above is verified by consensus of the relevant team(s) via a PR to update the stage. +
+ +## Checklist to move to Released + +- [ ] The work is published in stable versions of the relevant package(s) +- [ ] Deviations from the original RFC are noted in the RFC +- [ ] Release packages and dates are updated in the RFC frontmatter diff --git a/.github/README.md b/.github/README.md new file mode 100644 index 0000000000..1c2a7aafd0 --- /dev/null +++ b/.github/README.md @@ -0,0 +1,118 @@ +# emberjs/rfcs automation + +## Workflows + +### newly-added-rfc.yml + +This workflow runs on pull requests. The jobs gate on the first job which determines +if the pull request adds a new RFC. + +This has various checks to ensure new the RFC has correct metadata, filename, etc. + +This should be tested when updating actions/find-added-or-modified-rfcs or any of +the actions used within that action. See [testing](#testing). + +Test the following: +- [ ] Adding a new RFC. A new pull request should be opened with a new RFC, the + first job should correctly determine that an RFC has been added and the other + jobs should run. +- [ ] Modifying an RFC. A new pull request that modifies an existing RFC, the + first job should correctly determine that an RFC has not been added and the other + jobs should not run. + +### ci.yml + +This workflow runs on all pull requests and pushes to the primary branch. It +lints the frontmatter of all RFCs in the repository. + +### label-opened-new-rfc-prs.yml + +This workflow runs on pull requests. The jobs gate on the first job which determines +whether the pull request adds a new RFC. If it does, it labels the pull request with +'S-Proposed' as it is a newly proposed RFC. + +This should be tested when updating actions/find-added-or-modified-rfcs or any of +the actions used within that action. See [testing](#testing). + +Test the following: +- [ ] Adding a new RFC. A new pull request should be opened with a new RFC, the + first job should correctly determine that an RFC has been added and the other + jobs should run. The label `S-Proposed` should be added. +- [ ] Modifying an RFC. A new pull request that modifies an existing RFC, the + first job should correctly determine that an RFC has not been added and the other + jobs should not run. No label should be added. + +### advance-rfc.yml + +This workflow runs on pushes to the primary branch. The jobs gate on the first job +which determines if the push added an RFC or modified the stage of a previously-merged +RFC. + +Due to constraints in determining RFCs that have been modified, this workflow will +fail if the push modifies more than one RFC. If the push didn't modify the stage +of any of the modified RFCs, this can be completely okay. + +If an RFC stage was modified, this triggers the open-advancement-pr.yml workflow. + +This should be tested when updating actions/find-added-or-modified-rfcs or any of +the actions used within that action. See [testing](#testing). + +Test the following: +- [ ] Adding a new RFC. Merging a pull request that adds an RFC should open a + pull request to advance to the next stage using the correct template. +- [ ] Updating an RFC stage. Merging a pull request that modifies an existing RFC's + stage to something other than the last stage should open a pull request to + advance to the next stage using the correct template. +- [ ] Updating an RFC stage to the last stage. Merging a pull request that modifies + an existing RFC's stage to the final stage should NOT open a pull request. +- [ ] Modifying an RFC in any way that is not updating the stage. Merging a pull + request that does this should NOT open a pull request. + +### trigger-opening-advancement-pr.yml + +This workflow runs on workflow_dispatch and can be triggered from the GitHub UI. +It takes a path to an RFC and will open a PR to advance it to the next stage, if +applicable. + +Test the following: +- [ ] In the UI, on this workflow, trigger with a path of an existing RFC. A pull + request should be opened to advance the RFC to the next stage. +- [ ] In the UI, on this workflow, trigger with a path of an existing RFC at the + final stage. A pull request should NOT be opened. + +### open-advancement-pr.yml + +This workflow is used by the advance-rfc.yml workflow to open a pull request to +advance to the next stage. It is also used by the trigger-opening-advancement-pr.yml +workflow. + +This also generates an artifact named `advancement-prs` with files named `advance-rfc-XYX.json`. +There should be at most one file per RFC. The file contains the latest PR to +advance that RFC, along with other metadata. + +## generate-rfc-frontmatter-json.yml + +This workflow runs on pushes to the primary branch. It generates a JSON file with +all RFC frontmatter and is uploaded to an artifact named `rfc-data`. + +## Actions + +### find-added-or-modified-rfcs + +Gathers info about RFCs that have been added or modified in a pull request or push +(depending on inputs passed). + +### setup-rfcs-tooling + +Reusable action to checkout the rfcs-tooling repo and set it up for use. + +## PULL_REQUEST_TEMPLATE + +Directory of templates for use in opening stage advancement pull requests. + +## Testing +[Testing]: #testing + +Testing is primarily done by copying these actions and workflows to a test +repository and running the workflows +(see [kategengler/playground-ghs](https://github.com/kategengler/playground-ghas)). diff --git a/.github/actions/find-added-or-modified-rfcs/action.yml b/.github/actions/find-added-or-modified-rfcs/action.yml new file mode 100644 index 0000000000..df1c02ad8a --- /dev/null +++ b/.github/actions/find-added-or-modified-rfcs/action.yml @@ -0,0 +1,51 @@ +name: Find added or modified RFCs +description: 'Find added or modified RFC' + +# Any workflow using this action requires using actions/checkout with a fetch-depth: 0 + +inputs: + base-sha: + description: 'Base SHA' + required: false + sha: + description: 'SHA' + required: false + +outputs: + modified-rfc: + description: "The path of the RFC that was added or modified" + value: ${{ steps.modified-rfc.outputs.path }} + modified-rfcs-count: + description: "The count of how many RFCs were added or modified" + value: ${{ steps.counts.outputs.all_changed }} + added-rfcs-count: + description: "The count of how many RFCs that were added" + value: ${{ steps.counts.outputs.added }} + +runs: + using: "composite" + steps: + - name: Find added or modified RFCs + id: rfcs + uses: tj-actions/changed-files@v31 + with: + path: 'text' + json: 'true' + sha: ${{ inputs.sha }} + base_sha: ${{ inputs.base-sha }} + + - name: Get counts of changed and added RFCs + id: counts + shell: bash + run: | + changed_len=`echo "${{ steps.rfcs.outputs.all_changed_files }}" | jq '. | length'` + echo "all_changed=$changed_len" >> $GITHUB_OUTPUT + added_len=`echo "${{ steps.rfcs.outputs.added_files }}" | jq '. | length'` + echo "added=$added_len" >> $GITHUB_OUTPUT + + - name: Find modified or added RFC info + id: modified-rfc + shell: bash + run: | + changed_file=`echo "${{ steps.rfcs.outputs.all_changed_files }}" | jq '.[0]'` + echo "path=$changed_file" >> $GITHUB_OUTPUT diff --git a/.github/actions/setup-rfcs-tooling/action.yml b/.github/actions/setup-rfcs-tooling/action.yml new file mode 100644 index 0000000000..f44e114eba --- /dev/null +++ b/.github/actions/setup-rfcs-tooling/action.yml @@ -0,0 +1,20 @@ +name: Setup RFCs Tooling +description: 'Setup RFCs Tooling' + +runs: + using: "composite" + steps: + - name: Checkout tools repo + uses: actions/checkout@v3 + with: + repository: emberjs/rfcs-tooling + path: rfcs-tooling + ref: 'v2.1.0' + + - uses: actions/setup-node@v3 + with: + node-version: 16 + + - run: yarn install + shell: bash + working-directory: rfcs-tooling diff --git a/.github/workflows/advance-rfc.yml b/.github/workflows/advance-rfc.yml new file mode 100644 index 0000000000..c0a26ec85d --- /dev/null +++ b/.github/workflows/advance-rfc.yml @@ -0,0 +1,85 @@ +name: Open PR to advance an RFC to the next stage + +on: + push: + branches: [ main, master ] + paths: + - 'text/*.md' + +jobs: + check-rfcs: + name: 'Did push advance the stage of an RFC?' + runs-on: ubuntu-latest + outputs: + new-stage: ${{ steps.new-stage.outputs.value }} + rfc-number: ${{ steps.modified-rfc.outputs.rfc-number }} + modified-rfc: ${{ steps.rfcs.outputs.modified-rfc }} + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup RFCs tooling + uses: ./.github/actions/setup-rfcs-tooling + + - name: RFCs Added or Changed + id: rfcs + uses: ./.github/actions/find-added-or-modified-rfcs + with: + base-sha: ${{ github.event.before }} + + - name: Fail if more than 1 RFC is added or modified + if: steps.rfcs.outputs.modified-rfcs-count > 1 + run: | + echo "## More than one RFC added or modified" >> $GITHUB_STEP_SUMMARY + echo "This workflow is unable to determine if the stage of any of the added or modified RFCs have changed" >> $GITHUB_STEP_SUMMARY + echo "If this DID NOT modify the stage of any RFC, this failure may be ok" >> $GITHUB_STEP_SUMMARY + echo "::error::More than 1 RFC is added or modified in this PR; unable to automatically open PRs for advancement" + exit 1 + + - name: Find modified RFC Number + id: modified-rfc + run: | + changed_file=${{ steps.rfcs.outputs.modified-rfc }} + rfc_number="${changed_file//[!0-9]/}" + echo "RFC Number: $rfc_number" + echo "rfc-number=$rfc_number" >> $GITHUB_OUTPUT + + - name: Determine if stage has changed + id: has-stage-changed + continue-on-error: true + run: | + if [[ ${{ steps.rfcs.outputs.added-rfcs-count }} == 1 ]]; then + echo "## Yes, added a new RFC" >> $GITHUB_STEP_SUMMARY + echo "A new RFC was added" + echo "value=true" >> $GITHUB_OUTPUT + else + node rfcs-tooling/has-stage-changed.js ${{ github.event.before }} ${{ steps.rfcs.outputs.modified-rfc }} + if [[ $? == 0 ]]; then + echo "## Yes, stage has changed" >> $GITHUB_STEP_SUMMARY + echo "value=true" >> $GITHUB_OUTPUT + else + echo "## No, stage unchanged or at final stage" >> $GITHUB_STEP_SUMMARY + echo "value=false" >> $GITHUB_OUTPUT + fi + fi + + - name: Find new stage + if: steps.has-stage-changed.outputs.value == 'true' + id: new-stage + run: | + new_stage=`node rfcs-tooling/find-next-stage.js ${{ steps.rfcs.outputs.modified-rfc }}` + echo "New Stage: $new_stage" + echo "value=$new_stage" >> $GITHUB_OUTPUT + + advance-rfc: + uses: ./.github/workflows/open-advancement-pr.yml + needs: [ check-rfcs ] + if: needs.check-rfcs.outputs.new-stage + with: + rfc-path: ${{ needs.check-rfcs.outputs.modified-rfc }} + rfc-number: ${{ needs.check-rfcs.outputs.rfc-number }} + new-stage: ${{ needs.check-rfcs.outputs.new-stage }} + secrets: + personal-access-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 04f23a8f3e..3d282623b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: CI on: push: - branches: [master] + branches: [master, main] pull_request: {} jobs: @@ -11,17 +11,8 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Checkout tools repo - uses: actions/checkout@v3 - with: - repository: emberjs/rfcs-tooling - path: rfcs-tooling - ref: 'v1.1.0' - - - uses: actions/setup-node@v3 - - - run: yarn install - working-directory: rfcs-tooling + - name: Setup RFCs tooling + uses: ./.github/actions/setup-rfcs-tooling - name: Lint the frontmatter of all RFCs - run: node ./rfcs-tooling/lint-rfc-frontmatter.js text/*.md \ No newline at end of file + run: node ./rfcs-tooling/lint-rfc-frontmatter.js text/*.md diff --git a/.github/workflows/ensure-filename.yml b/.github/workflows/ensure-filename.yml deleted file mode 100644 index d8dce762bd..0000000000 --- a/.github/workflows/ensure-filename.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Ensure Filename of RFCs - -on: - pull_request: - paths: - - 'text/*.md' - -jobs: - check-filename: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Get Changed Files - uses: lots0logs/gh-action-get-changed-files@2.1.4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Filter Added Files to Added RFCs - id: files - run: | - added_files=`jq -r '[.[] | select(startswith("text/"))] | join(" ")' ${HOME}/files_added.json` - echo "::set-output name=added::$added_files" - - - name: Checkout tools repo - uses: actions/checkout@v2 - with: - repository: emberjs/rfcs-tooling - path: rfcs-tooling - - - uses: actions/setup-node@v2.1.2 - - - run: yarn install - working-directory: rfcs-tooling - - - name: Test RFC Filename matches PR Number that adds it - env: - PR_NUMBER: ${{ github.event.pull_request.number }} - run: node check-filename-matches-pr.js $PR_NUMBER ${{ steps.files.outputs.added }} - working-directory: rfcs-tooling diff --git a/.github/workflows/generate-rfc-frontmatter-json.yml b/.github/workflows/generate-rfc-frontmatter-json.yml new file mode 100644 index 0000000000..ae0429662b --- /dev/null +++ b/.github/workflows/generate-rfc-frontmatter-json.yml @@ -0,0 +1,27 @@ +name: Generate a JSON file of all frontmatter + +on: + push: + branches: [ main, master ] + paths: + - 'text/*.md' + +jobs: + generate-rfc-frontmatter-data-artifact: + name: 'Generate a JSON file of RFC status' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Setup RFCs tooling + uses: ./.github/actions/setup-rfcs-tooling + + - name: Generate frontmatter data file + run: | + node rfcs-tooling/list-frontmatter.js text/*.md > rfc-data.json + + - uses: actions/upload-artifact@v3 + with: + name: rfc-data + path: rfc-data.json + if-no-files-found: error diff --git a/.github/workflows/label-opened-new-rfc-prs.yml b/.github/workflows/label-opened-new-rfc-prs.yml new file mode 100644 index 0000000000..ce723898c3 --- /dev/null +++ b/.github/workflows/label-opened-new-rfc-prs.yml @@ -0,0 +1,26 @@ +name: Label newly opened RFC PRs + +on: + pull_request_target: # This workflow has permissions on the repo, do NOT run code from PRs in this workflow. See https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ + types: [opened] + paths: + - 'text/*.md' + +jobs: + label-pr: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + persist-credentials: false + + - name: RFCs Added or Changed + id: rfcs + uses: ./.github/actions/find-added-or-modified-rfcs + + - uses: actions-ecosystem/action-add-labels@v1 + if: steps.rfcs.outputs.added-rfcs-count > 0 + with: + labels: S-Proposed diff --git a/.github/workflows/newly-added-rfcs.yml b/.github/workflows/newly-added-rfcs.yml new file mode 100644 index 0000000000..4331efa33d --- /dev/null +++ b/.github/workflows/newly-added-rfcs.yml @@ -0,0 +1,142 @@ +name: Newly Added RFC + +# Runs various checks on pull requests that add new RFCs + +on: + pull_request: + types: [opened, labeled, unlabeled, synchronize, reopened, ready_for_review] + paths: + - 'text/*.md' + +concurrency: + # Events within 5 minutes are not guaranteed to run in order, and so when removing S-Proposed and adding S-Exploring + # we can't guarantee that the run of the workflow will be the one where S-Exploring is added. Adding `github.event_name` + # to the concurrency allows both workflows to complete and the PR to eventually have successful checks. + group: newly-added-rfc-${{ github.head_ref || github.ref }}-${{ github.event_name }} + cancel-in-progress: true + +jobs: + check-rfcs: + name: Does PR add RFCs? + runs-on: ubuntu-latest + outputs: + rfcs-added: ${{ steps.rfcs.outputs.added-rfcs-count > 0 }} + rfcs-changed: ${{ steps.rfcs.outputs.modified-rfcs-count }} + modified-rfc: ${{ steps.rfcs.outputs.modified-rfc }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: RFCs Added or Changed + id: rfcs + uses: ./.github/actions/find-added-or-modified-rfcs + + - name: Debug output + run: | + echo "RFC Added count: ${{ steps.rfcs.outputs.added-rfcs-count }}" + echo "RFC Changed count: ${{ steps.rfcs.outputs.modified-rfcs-count }}" + echo "RFC: ${{ steps.rfcs.outputs.modified-rfc }}" + if [[ ${{ steps.rfcs.outputs.added-rfcs-count }} == 1 ]]; then + echo "## RFC Added in this PR!!!" >> $GITHUB_STEP_SUMMARY + elif [[ ${{steps.rfcs.outputs.added-rfcs-count}} == 0 ]]; then + echo "## No RFCs added in this PR" >> $GITHUB_STEP_SUMMARY + fi + + check-in-exploring: + name: Stage must be 'Exploring' (via label) for new RFC before merging + if: needs.check-rfcs.outputs.rfcs-added == 'true' + runs-on: ubuntu-latest + needs: [check-rfcs] + steps: + - name: Ensure the RFC is in the Exploring Stage before merge is allowed + if: ${{ !contains(github.event.pull_request.labels.*.name, 'S-Exploring') }} + run: | + echo "::error::Newly added RFCs must advance to the Exploring Stage (via label) before merging to Accepted is allowed" + exit 1 + + verify-only-in-one-stage: + name: RFC must be in only one stage before merging (labels) + runs-on: ubuntu-latest + needs: [check-rfcs] + if: needs.check-rfcs.outputs.rfcs-added == 'true' + steps: + - name: Ensure the RFC only has one stage + if: contains(github.event.pull_request.labels.*.name, 'S-Exploring') && contains(github.event.pull_request.labels.*.name, 'S-Proposed') + run: | + echo "::error::Newly added RFC must only have one stage label" + exit 1 + + only-one-rfc-added: + name: Only one RFC can be added in a PR + runs-on: ubuntu-latest + needs: [ check-rfcs ] + if: needs.check-rfcs.outputs.rfcs-added == 'true' + steps: + - name: Fail if more than 1 RFC is added or modified + if: ${{ needs.check-rfcs.outputs.rfcs-changed > 1}} + run: | + echo "::error::More than 1 RFC is added in this PR; will be unable to automatically open PRs for advancement" + exit 1 + + frontmatter-stage-is-accepted: + name: Frontmatter stage must be 'accepted' before merging + runs-on: ubuntu-latest + needs: [ check-rfcs ] + if: needs.check-rfcs.outputs.rfcs-added == 'true' + steps: + - uses: actions/checkout@v3 + + - name: Setup RFCs tooling + uses: ./.github/actions/setup-rfcs-tooling + + - name: Verify stage of newly added RFC is `accepted` in frontmatter + run: | + frontmatter=`node rfcs-tooling/rfc-frontmatter.js ${{ needs.check-rfcs.outputs.modified-rfc }}` + stage=`echo $frontmatter | jq '.stage'` + if [[ $stage != '"accepted"' ]]; then + echo "::error::Newly added RFCs must have the stage 'accepted' in the frontmatter" + exit 1 + fi + + check-filename: + name: Filename matches RFC number + runs-on: ubuntu-latest + needs: [ check-rfcs ] + if: needs.check-rfcs.outputs.rfcs-added == 'true' + steps: + - uses: actions/checkout@v3 + + - name: Setup RFCs tooling + uses: ./.github/actions/setup-rfcs-tooling + + - name: Test RFC Filename matches PR Number that adds it + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + run: node check-filename-matches-pr.js $PR_NUMBER ${{ needs.check-rfcs.outputs.modified-rfc }} + working-directory: rfcs-tooling + + check-accepted-pr-url: + name: Verify Accepted PR URL is correct + runs-on: ubuntu-latest + needs: [ check-rfcs ] + if: needs.check-rfcs.outputs.rfcs-added == 'true' + steps: + - uses: actions/checkout@v3 + + - name: Setup RFCs tooling + uses: ./.github/actions/setup-rfcs-tooling + + - name: Verify Accepted PR URL is correct + run: | + frontmatter=`node rfcs-tooling/rfc-frontmatter.js ${{ needs.check-rfcs.outputs.modified-rfc }}` + accepted_pr=`echo $frontmatter | jq '.prs.accepted'` + accepted_pr=${accepted_pr//\"/} + expected_pr="${{ github.event.pull_request.html_url }}" + expected_pr=${expected_pr//\"/} + if [[ $accepted_pr != $expected_pr ]]; then + echo "Accepted PR in frontmatter: $accepted_pr" + echo "Expected PR in frontmatter: $expected_pr" + echo "::error::Accepted PR URL is incorrect, please update the frontmatter prs.accepted to \"${{ github.event.pull_request.html_url }}\"" + exit 1 + fi diff --git a/.github/workflows/open-advancement-pr.yml b/.github/workflows/open-advancement-pr.yml new file mode 100644 index 0000000000..a4e59a87dc --- /dev/null +++ b/.github/workflows/open-advancement-pr.yml @@ -0,0 +1,92 @@ +name: Reusable workflow to open advancement PRs + +on: + workflow_call: + inputs: + new-stage: + required: true + type: string + rfc-path: + required: true + type: string + rfc-number: + required: true + type: string + secrets: + personal-access-token: + required: true + +jobs: + advance-rfc: + name: Open PR to advance RFC to the next stage + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Setup RFCs tooling + uses: ./.github/actions/setup-rfcs-tooling + + - name: Update frontmatter + run: | + node rfcs-tooling/update-rfc-stage.js ${{ inputs.new-stage }} ${{ inputs.rfc-path }} + + - name: Set variables for use in PR + id: pr-variables + run: | + frontmatter=`node rfcs-tooling/rfc-frontmatter.js ${{ inputs.rfc-path }}` + ready_for_release_pr=`echo $frontmatter | jq '.prs."ready-for-release"'` + ready_for_release_pr=${ready_for_release_pr//\"/} + released_pr=`echo $frontmatter | jq '.prs.released'` + released_pr=${released_pr//\"/} + if [[ ${{ inputs.new-stage }} == "ready-for-release" ]]; then + pretty_stage="Ready for Release" + template=`sed -e 's/__RFC_NUMBER__/${{ inputs.rfc-number }}/g' .github/PULL_REQUEST_TEMPLATE/advance-to-ready-for-release.md` + elif [[ ${{ inputs.new-stage }} == "released" ]]; then + pretty_stage="Released" + template=`sed -e 's/__RFC_NUMBER__/${{ inputs.rfc-number }}/g' -e "s>__READY_FOR_RELEASE_PR__>$ready_for_release_pr>g" .github/PULL_REQUEST_TEMPLATE/advance-to-released.md` + elif [[ ${{ inputs.new-stage }} == "recommended" ]]; then + pretty_stage="Recommended" + template=`sed -e 's/__RFC_NUMBER__/${{ inputs.rfc-number }}/g' -e "s>__READY_FOR_RELEASE_PR__>$ready_for_release_pr>g" -e "s>__RELEASED_PR__>$released_pr>g" .github/PULL_REQUEST_TEMPLATE/advance-to-recommended.md` + fi + echo 'body<> $GITHUB_OUTPUT + echo "$template" >> $GITHUB_OUTPUT + echo 'EOF' >> $GITHUB_OUTPUT + echo "Pretty Stage: $pretty_stage" + echo "pretty-stage=$pretty_stage" >> $GITHUB_OUTPUT + + - name: Open PR + id: create-pr + uses: peter-evans/create-pull-request@v4.2.0 + with: + token: ${{ secrets.personal-access-token }} + commit-message: "Advance RFC to Stage ${{ inputs.new-stage }}" + add-paths: 'text' + branch: "advance-rfc-${{ inputs.rfc-number }}" + title: "Advance RFC #${{ inputs.rfc-number}} to Stage ${{ steps.pr-variables.outputs.pretty-stage }}" + body: "${{ steps.pr-variables.outputs.body }}" + labels: "RFC Advancement,S-${{ steps.pr-variables.outputs.pretty-stage}}" + draft: true + + - name: Add new PR link to RFC frontmatter + run: | + node rfcs-tooling/update-advancement-pr.js ${{ inputs.rfc-path }} ${{ inputs.new-stage}} ${{ steps.create-pr.outputs.pull-request-url }} + + - name: Update PR + run: | + git config --local user.email 'ember-rfcs@example.com' + git config --local user.name 'Ember.js RFCS CI' + git add ${{ inputs.rfc-path }} + git commit -m "Update RFC ${{ inputs.rfc-number }} ${{ inputs.new-stage }} PR URL" + git push origin advance-rfc-${{ inputs.rfc-number }} + echo "## Opened PR ${{ steps.create-pr.outputs.pull-request-url }}" >> $GITHUB_STEP_SUMMARY + + - name: Add PR to artifact + run: | + echo '{ "file": "${{ inputs.rfc-path }}", "number": "${{ inputs.rfc-number }}", "pr": "${{ steps.create-pr.outputs.pull-request-url }}", "advancementStage": "${{ inputs.new-stage }}" }' > advance-rfc-${{ inputs.rfc-number }}.json + + - name: Upload artifact of open RFC PRs + uses: actions/upload-artifact@v3 + with: + name: advancement-prs + path: advance-rfc-${{ inputs.rfc-number }}.json + if-no-files-found: error diff --git a/.github/workflows/trigger-opening-advancement-pr.yml b/.github/workflows/trigger-opening-advancement-pr.yml new file mode 100644 index 0000000000..60c06b0b7b --- /dev/null +++ b/.github/workflows/trigger-opening-advancement-pr.yml @@ -0,0 +1,50 @@ +name: Trigger the opening of a PR to advance an RFC to the next stage + +on: + workflow_dispatch: + inputs: + rfc-path: + type: string + required: true + description: Path to the RFC to open PR for advancement to the next stage + +jobs: + gather-rfc-info: + name: 'Gather RFC info' + runs-on: ubuntu-latest + outputs: + new-stage: ${{ steps.new-stage.outputs.value }} + rfc-number: ${{ steps.rfc.outputs.rfc-number }} + + steps: + - uses: actions/checkout@v3 + + - name: Setup RFCs tooling + uses: ./.github/actions/setup-rfcs-tooling + + - name: Find RFC Number + id: rfc + run: | + rfc=${{ inputs.rfc-path }} + rfc_number="${rfc//[!0-9]/}" + echo "RFC Number: $rfc_number" + echo "rfc-number=$rfc_number" >> $GITHUB_OUTPUT + + - name: Find new stage + id: new-stage + run: | + new_stage=`node rfcs-tooling/find-next-stage.js ${{ inputs.rfc-path }}` + echo "New Stage: $new_stage" + echo "value=$new_stage" >> $GITHUB_OUTPUT + + + advance-rfc: + uses: ./.github/workflows/open-advancement-pr.yml + needs: [ gather-rfc-info ] + if: needs.gather-rfc-info.outputs.new-stage + with: + rfc-path: ${{ inputs.rfc-path }} + rfc-number: ${{ needs.gather-rfc-info.outputs.rfc-number }} + new-stage: ${{ needs.gather-rfc-info.outputs.new-stage }} + secrets: + personal-access-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}