From 469aaf6088e52b9fc3e2ace25cbda0d85c110d9b Mon Sep 17 00:00:00 2001 From: "Matthew R. Becker" Date: Tue, 3 Sep 2024 12:25:39 +0200 Subject: [PATCH] feat: leave file in tree, draft PRs (#57) * feat: leave file in tree * fix: bug in action * fix: make this pass * fix: make this pass * fix: bug in test output * fix: make sure lock file is old in test * fix: make tests pass hopefully * fix: try this * feat: add draft for PRs * Update action.yml --- .github/workflows/tests.yml | 81 ++++++++++++++++++++++++++++++++----- README.md | 23 ++++++++--- action.yml | 80 ++++++++++++++++++++++++++++-------- 3 files changed, 151 insertions(+), 33 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1a0010c..0c6edde 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -56,10 +56,11 @@ jobs: lock-file: conda-lock.yml ignored-packages: '' relock-all-packages: false - github-token: ${{ secrets.GH_PAT }} + github-token: ${{ secrets.GITHUB_TOKEN }} automerge: false base-branch: ${{ github.head_ref }} head-branch: tests-lock + draft: true - name: did it relock? if: steps.relock.outputs.relocked != 'true' @@ -80,7 +81,7 @@ jobs: grep numpy conda-lock.yml grep python conda-lock.yml env: - GH_TOKEN: ${{ secrets.GH_PAT }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: close PR if: always() @@ -88,7 +89,61 @@ jobs: shell: bash run: gh pr close ${{ steps.relock.outputs.pull-request-number }} env: - GH_TOKEN: ${{ secrets.GH_PAT }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + tests-file: + name: test updates w/ file + runs-on: "ubuntu-latest" + if: github.event.pull_request.title != 'relock w/ conda-lock' + steps: + - uses: actions/checkout@v4 + + - uses: conda-incubator/setup-miniconda@v3 + with: + python-version: 3.11 + channels: conda-forge + channel-priority: strict + show-channel-urls: true + miniforge-version: latest + + - name: make the lock file + shell: bash -leo pipefail {0} + run: | + conda install --yes conda-lock + cp test-env.yml old-test-env.yml + echo " - python =3.8" >> old-test-env.yml + conda-lock lock --file old-test-env.yml + + - name: make a copy of lock file + shell: bash -leo pipefail {0} + run: | + cp conda-lock.yml old-conda-lock.yml + + - name: relock + id: relock + uses: ./ + with: + environment-file: test-env.yml + lock-file: conda-lock.yml + ignored-packages: '' + relock-all-packages: false + github-token: ${{ secrets.GITHUB_TOKEN }} + action: file + draft: true + + - name: did it relock? + if: steps.relock.outputs.relocked != 'true' + run: exit 1 + + - name: test that lock file is different + if: steps.relock.outputs.relocked == 'true' + shell: bash + run: | + val=$(diff conda-lock.yml old-conda-lock.yml || :) + if [[ "${val}" == "" ]]; then + echo "lock files are the same" + exit 1 + fi tests-no-lock: name: test no update @@ -119,10 +174,11 @@ jobs: lock-file: conda-lockk.yml ignored-packages: '' relock-all-packages: false - github-token: ${{ secrets.GH_PAT }} + github-token: ${{ secrets.GITHUB_TOKEN }} automerge: false base-branch: ${{ github.head_ref }} head-branch: tests-no-lock + draft: true - name: did it not relock? if: steps.relock.outputs.relocked == 'true' @@ -134,7 +190,7 @@ jobs: shell: bash run: gh pr close ${{ steps.relock.outputs.pull-request-number }} env: - GH_TOKEN: ${{ secrets.GH_PAT }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} tests-skip-existing-part-1: name: test skip existing part 1 @@ -153,10 +209,11 @@ jobs: lock-file: conda-lock.yml ignored-packages: '' relock-all-packages: false - github-token: ${{ secrets.GH_PAT }} + github-token: ${{ secrets.GITHUB_TOKEN }} automerge: false base-branch: ${{ github.head_ref }} head-branch: tests-skip-existing + draft: true - name: did it relock? if: steps.relock.outputs.relocked != 'true' @@ -177,7 +234,7 @@ jobs: grep numpy conda-lock.yml grep python conda-lock.yml env: - GH_TOKEN: ${{ secrets.GH_PAT }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} tests-skip-existing-part-2: name: test skip existing part 2 @@ -195,11 +252,12 @@ jobs: lock-file: conda-lock.yml ignored-packages: '' relock-all-packages: false - github-token: ${{ secrets.GH_PAT }} + github-token: ${{ secrets.GITHUB_TOKEN }} automerge: false base-branch: ${{ github.head_ref }} head-branch: tests-skip-existing skip-if-pr-exists: true + draft: true - name: did it relock? if: steps.relock.outputs.relocked == 'true' @@ -211,7 +269,7 @@ jobs: shell: bash run: gh pr close ${{ needs.tests-skip-existing-part-1.outputs.pull-request-number }} env: - GH_TOKEN: ${{ secrets.GH_PAT }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} tests-ignore: name: test ignore @@ -227,13 +285,14 @@ jobs: environment-file: test-env.yml lock-file: outdated-conda-lock.yml relock-all-packages: false - github-token: ${{ secrets.GH_PAT }} + github-token: ${{ secrets.GITHUB_TOKEN }} automerge: false base-branch: ${{ github.head_ref }} head-branch: tests-ignore ignored-packages: | python numpy + draft: true - name: did it not relock? if: steps.relock.outputs.relocked == 'true' @@ -245,4 +304,4 @@ jobs: shell: bash run: gh pr close ${{ steps.relock.outputs.pull-request-number }} env: - GH_TOKEN: ${{ secrets.GH_PAT }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 7af0c9f..6b416d8 100644 --- a/README.md +++ b/README.md @@ -26,32 +26,43 @@ jobs: github-token: ${{ secrets.GITHUB_PAT }} # files to relock w/ conda-lock - # environment-file: environment.yml # default - # lock-file: conda-lock.yml # default + environment-file: environment.yml # default + lock-file: conda-lock.yml # default # optional list of packages whose changes are ignore when relocking + ignored-packages: "" # default # ignored-packages: "numpy,scipy" # use only these packages to determine if a relock is needed + include-only-packages: "" # default # include-only-packages: "numpy,scipy" # whether to relock on an update to any package in the environment, # not just those in the environment file - # relock-all-packages: false # default + relock-all-packages: false # default + # action to take if we relock + # one of 'pr' (make a PR) or 'file' (leave new lock file in CWD) + action: 'pr' # default + + # these options apply only if we are making PRs # automerge the PR - you need to have GitHub automerge enabled - # automerge: false # default + automerge: false # default # use this setting to fix issues with the base branch not # being inferred correctly # See https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#events-which-checkout-a-commit + base-branch: "" # default # base-branch: blah # the head branch for PRs - # head-branch: relock-conda # default + head-branch: relock-conda # default # whether to skip relocking if a PR already exists - # skip-if-pr-exists: false # default + skip-if-pr-exists: false # default + + # whether to open the PR as a draft + draft: false # default ``` See the [action.yml](action.yml) for details on possible inputs and options. diff --git a/action.yml b/action.yml index d3187a7..633365a 100644 --- a/action.yml +++ b/action.yml @@ -31,6 +31,12 @@ inputs: github-token: description: 'GitHub personal access token to use for making PRs' required: true + action: + description: > + the action to take if the lock file is updated: `pr` will make a PR; `file` will leave the updated lock file + in the current working directory + required: true + default: 'pr' automerge: description: 'whether to automatically merge the PR' required: true @@ -48,6 +54,10 @@ inputs: description: 'whether to skip relocking if a PR already exists' required: true default: false + draft: + description: 'whether to open the PR as a draft' + required: true + default: false outputs: pull-request-number: @@ -65,19 +75,27 @@ runs: id: check shell: bash -leo pipefail {0} run: | - prs=$(gh pr list \ - --repo "$GITHUB_REPOSITORY" \ - --head '${{ inputs.head-branch }}' \ - --json title \ - --jq 'map(select(.title == "relock w/ conda-lock")) | length') - if [[ ${prs} != "0" && ${SKIP_IF_PR_EXISTS} == "true" ]]; then - echo "skip=true" >> "$GITHUB_OUTPUT" + if [[ "${INPUT_ACTION}" != "pr" ]]; then + res="false" else - echo "skip=false" >> "$GITHUB_OUTPUT" + prs=$(gh pr list \ + --repo "$GITHUB_REPOSITORY" \ + --head '${{ inputs.head-branch }}' \ + --json title \ + --jq 'map(select(.title == "relock w/ conda-lock")) | length') + + if [[ ${prs} != "0" && ${SKIP_IF_PR_EXISTS} == "true" ]]; then + res="true" + else + res="false" + fi fi + + echo "skip=${res}" >> "$GITHUB_OUTPUT" env: GH_TOKEN: ${{ inputs.github-token }} SKIP_IF_PR_EXISTS: ${{ inputs.skip-if-pr-exists }} + INPUT_ACTION: ${{ inputs.action }} - name: setup conda-lock if: ${{ steps.check.outputs.skip != 'true' }} @@ -117,7 +135,10 @@ runs: - name: open PR id: pr - if: steps.check.outputs.skip != 'true' && steps.relock.outputs.env_relocked == 'true' + if: >- + steps.check.outputs.skip != 'true' + && steps.relock.outputs.env_relocked == 'true' + && inputs.action == 'pr' uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6 with: commit-message: relock w/ conda-lock @@ -131,9 +152,15 @@ runs: token: ${{ inputs.github-token }} labels: dependencies base: ${{ inputs.base-branch }} + draft: ${{ inputs.draft }} - name: automerge - if: steps.check.outputs.skip != 'true' && inputs.automerge == 'true' && steps.relock.outputs.env_relocked == 'true' && steps.pr.outputs.pull-request-number != '' + if: >- + steps.check.outputs.skip != 'true' + && inputs.automerge == 'true' + && steps.relock.outputs.env_relocked == 'true' + && steps.pr.outputs.pull-request-number != '' + && inputs.action == 'pr' shell: bash -leo pipefail {0} run: gh pr merge --merge --auto "${{ steps.pr.outputs.pull-request-number }}" env: @@ -144,10 +171,31 @@ runs: if: always() shell: bash -leo pipefail {0} run: | - if [[ '${{ steps.check.outputs.skip }}' == 'true' ]]; then - echo "relocked=false" >> "$GITHUB_OUTPUT" - elif [[ '${{ steps.relock.outputs.env_relocked }}' == 'true' && '${{ steps.pr.outputs.pull-request-number }}' != '' ]]; then - echo "relocked=true" >> "$GITHUB_OUTPUT" - else - echo "relocked=false" >> "$GITHUB_OUTPUT" + res="" + + # if we skipped, we did not relock + if [[ "${res}" == "" && '${{ steps.check.outputs.skip }}' == 'true' ]]; then + res="false" + fi + + # if the env was relocked, then we look at PR vs file + if [[ "${res}" == "" && '${{ steps.relock.outputs.env_relocked }}' == 'true' ]]; then + # for a PR, we need to know if it was opened + if [[ '${{ inputs.action }}' == 'pr' ]]; then + if [[ '${{ steps.pr.outputs.pull-request-number }}' != '' ]]; then + res="true" + else + res="false" + fi + else + # if not a PR, then we updated the file + res="true" + fi fi + + # if we get here, default to false + if [[ "${res}" == "" ]]; then + res="false" + fi + + echo "relocked=${res}" >> "$GITHUB_OUTPUT"