Skip to content

Commit

Permalink
feat: Add an action that can be used to fetch a PR number (#32)
Browse files Browse the repository at this point in the history
* feat: Add an action that can be used to fetch a PR number

* test: Add test for PR from a fork

* docs: Add documentation on the new action
  • Loading branch information
nfelt14 authored Aug 30, 2024
1 parent 624f555 commit 2ae3d4d
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 13 deletions.
19 changes: 13 additions & 6 deletions .github/workflows/_reusable-publish-api-comparison.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,32 @@ jobs:
else
echo "BREAKING_CHANGES=true" >> "$GITHUB_ENV"
fi
- name: Fetch PR number
id: pr
uses: 8BitJonny/gh-get-current-pr@08e737c57a3a4eb24cec6487664b243b77eb5e36
- if: ${{ endsWith(github.repository, '/python-package-ci-cd') }} # Run the local action when this is run in the python-package-ci-cd repository
id: fetch-pr-number-local
uses: ./actions/fetch_pr_number
with:
sha: ${{ github.event.workflow_run.head_sha }}
github-repository: ${{ github.repository }}
- if: ${{ !endsWith(github.repository, '/python-package-ci-cd') }} # Run the public action when this is run outside the python-package-ci-cd repository
id: fetch-pr-number
uses: tektronix/python-package-ci-cd/actions/[email protected]
with:
sha: ${{ github.event.workflow_run.head_sha }}
github-repository: ${{ github.repository }}
- name: Publish API Breaking Changes Check Results
uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31
if: ${{ env.BREAKING_CHANGES == 'true' }}
with:
header: breaking-api-changes
number: ${{ steps.pr.outputs.number }}
number: ${{ steps.fetch-pr-number.outputs.number || steps.fetch-pr-number-local.outputs.number }}
recreate: true
path: artifacts/breaking_changes.md
- name: Add workflow link to comment
if: ${{ env.BREAKING_CHANGES == 'true' }}
uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31
with:
header: breaking-api-changes
number: ${{ steps.pr.outputs.number }}
number: ${{ steps.fetch-pr-number.outputs.number || steps.fetch-pr-number-local.outputs.number }}
append: true
message: |-
<p><a href="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}">Link to workflow run</a></p>
Expand All @@ -50,5 +57,5 @@ jobs:
uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31
with:
header: breaking-api-changes
number: ${{ steps.pr.outputs.number }}
number: ${{ steps.fetch-pr-number.outputs.number || steps.fetch-pr-number-local.outputs.number }}
delete: true
17 changes: 12 additions & 5 deletions .github/workflows/_reusable-publish-test-results.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,30 @@ jobs:
run_id: ${{ github.event.workflow_run.id }}
name: artifact_${{ matrix.os-name }}_tests
path: artifacts
- name: Fetch PR number
id: pr
uses: 8BitJonny/gh-get-current-pr@08e737c57a3a4eb24cec6487664b243b77eb5e36
- if: ${{ endsWith(github.repository, '/python-package-ci-cd') }} # Run the local action when this is run in the python-package-ci-cd repository
id: fetch-pr-number-local
uses: ./actions/fetch_pr_number
with:
sha: ${{ github.event.workflow_run.head_sha }}
github-repository: ${{ github.repository }}
- if: ${{ !endsWith(github.repository, '/python-package-ci-cd') }} # Run the public action when this is run outside the python-package-ci-cd repository
id: fetch-pr-number
uses: tektronix/python-package-ci-cd/actions/[email protected]
with:
sha: ${{ github.event.workflow_run.head_sha }}
github-repository: ${{ github.repository }}
- name: Publish Test Results
uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31
with:
header: test-results-${{ matrix.os-name }}
number: ${{ steps.pr.outputs.number }}
number: ${{ steps.fetch-pr-number.outputs.number || steps.fetch-pr-number-local.outputs.number }}
recreate: true
path: artifacts/.results_tests/github_report.md
- name: Add workflow link to comment
uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31
with:
header: test-results-${{ matrix.os-name }}
number: ${{ steps.pr.outputs.number }}
number: ${{ steps.fetch-pr-number.outputs.number || steps.fetch-pr-number-local.outputs.number }}
append: true
message: |-
<p><a href="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}">Link to workflow run</a></p>
50 changes: 50 additions & 0 deletions .github/workflows/test-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,63 @@ jobs:
dependency-dict: '{"dev": ["pyright"]}'
pre-commit-hook-skip-list: remove-tabs,forbid-tabs,check-readthedocs,check-dependabot,check-github-actions,check-github-workflows,commitizen,blacken-docs,yamlfix,hadolint,mdformat,markdown-link-check,check-poetry,toml-sort-fix,pyright,poetry-audit,ruff,ruff-format,docformatter
export-dependency-groups: udd:actions/update_development_dependencies,cutv:actions/create_unique_testpypi_version,fci:actions/find_unreleased_changelog_items,tests
test-fetch_pr_number:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Fetch known PR number
uses: ./actions/fetch_pr_number
id: fetch-pr-number-found
with:
sha: 7a6fb39bda8ace8217530c3bc79407333462fc30
github-repository: ${{ github.repository }}
- name: Verify the PR number
run: |
if [ "${{ steps.fetch-pr-number-found.outputs.number }}" != "30" ]; then
echo "The fetched PR number doesn't match the expected PR number."
echo "Expected: 30"
echo "Actual: ${{ steps.fetch-pr-number-found.outputs.number }}"
exit 1
fi
- name: Fetch known PR number from a fork
uses: ./actions/fetch_pr_number
id: fetch-pr-number-found-fork
with:
sha: 9163270797352721c78d82054f6ead259f2f7366
github-repository: ${{ github.repository }}
- name: Verify the PR number from a fork
run: |
if [ "${{ steps.fetch-pr-number-found-fork.outputs.number }}" != "31" ]; then
echo "The fetched PR number doesn't match the expected PR number."
echo "Expected: 31"
echo "Actual: ${{ steps.fetch-pr-number-found.outputs.number }}"
exit 1
fi
- name: Fetch unknown PR number
uses: ./actions/fetch_pr_number
id: fetch-pr-number-not-found
with:
sha: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
github-repository: ${{ github.repository }}
max-attempts: 2
retry-delay: 2
continue-on-error: true # This step should fail
- name: Verify no PR number was found and the previous step failed
run: |
if [ "${{ steps.fetch-pr-number-not-found.outcome }}" != "failure" ]; then
echo "Step did not fail as expected."
exit 1
else
echo "Step failed as expected."
fi
# Check that all jobs passed
check-action-tests-passed:
if: ${{ !cancelled() }}
needs:
- test-create_unique_testpypi_version
- test-find_unreleased_changelog_items
- test-update_development_dependencies
- test-fetch_pr_number
runs-on: ubuntu-latest
steps:
- name: Decide whether the needed jobs succeeded or failed
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ Valid subsections within a version are:

Things to be included in the next release go here.

### Added

- Added an action that can be used to fetch a PR number based on the `head_sha`.

### Changed

- Converted all references to third-party Actions used in Reusable Workflows from tags to SHAs to ensure that the workflows are stable and do not change unexpectedly.
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ Python Packaging CI/CD.
1. [`create_unique_testpypi_version`](actions/create_unique_testpypi_version/readme.md)
- This action creates a unique version number for the provided Python package to enable uploading
the package to [TestPyPI](https://test.pypi.org).
2. [`find_unreleased_changelog_items`](./actions/find_unreleased_changelog_items/readme.md)
2. [`fetch_pr_number`](actions/fetch_pr_number/readme.md)
- This action fetches the Pull Request number for the provided SHA in the provided GitHub repository.
3. [`find_unreleased_changelog_items`](./actions/find_unreleased_changelog_items/readme.md)
- This action will parse the repository's `CHANGELOG.md` file to determine if
there are any unreleased items. It will fail if it cannot find any unreleased
items, as this means that the package is not ready for a new release.
3. [`update_development_dependencies`](./actions/update_development_dependencies/readme.md)
4. [`update_development_dependencies`](./actions/update_development_dependencies/readme.md)
- This action enables updating Python development dependencies using the
[`Poetry`](https://python-poetry.org/) package manager in-sync with
[`pre-commit`](https://pre-commit.com/) hooks.
Expand Down
60 changes: 60 additions & 0 deletions actions/fetch_pr_number/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
name: Fetch PR Number
description: Find the PR number for the provided SHA. This action also works for PRs
that are from forks.
inputs:
sha:
description: The SHA of the commit to find the PR number for.
required: true
github-repository:
description: The GitHub repository to search for the PR in.
required: true
retry-delay:
description: The delay in seconds between retries.
default: '120'
required: false
max-attempts:
description: The maximum number of attempts to find the PR number.
default: '5'
required: false
outputs:
number:
description: The PR number.
value: ${{ steps.fetch-pr.outputs.result }}
runs:
using: composite
steps:
- name: Fetch PR number
id: fetch-pr
uses: actions/github-script@e69ef5462fd455e02edcaf4dd7708eda96b9eda0 # v7.0.0
with:
script: |-
const maxAttempts = ${{ inputs.max-attempts }};
let attempt = 0;
let pullRequestNumber;
while (attempt < maxAttempts) {
try {
const response = await github.rest.search.issuesAndPullRequests({
q: 'repo:${{ inputs.github-repository }} is:pr sha:${{ inputs.sha }}',
per_page: 1,
});
const items = response.data.items;
if (items.length < 1) {
throw new Error('No PRs found');
}
pullRequestNumber = items[0].number;
console.info("Pull request number is", pullRequestNumber);
break; // Exit loop on success
} catch (error) {
console.error(`Attempt ${attempt + 1} failed:`, error.message);
if (attempt < maxAttempts - 1) { // Check if not last attempt
console.log(`Waiting for ${{ inputs.retry-delay }} seconds before retrying...`);
await new Promise(resolve => setTimeout(resolve, ${{ inputs.retry-delay }} * 1000)); // Wait for 2 minutes
}
}
attempt++;
}
if (!pullRequestNumber) {
core.setFailed(`Failed to fetch PR number after ${maxAttempts} attempts`);
}
return pullRequestNumber;
41 changes: 41 additions & 0 deletions actions/fetch_pr_number/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# fetch_pr_number

This action fetches the Pull Request number for the provided SHA in the provided GitHub repository.
See the [example](#example) below for usage details.

## Inputs

| Input variable | Necessity | Description | Default |
| ------------------- | --------- | ----------------------------------------------------- | ------- |
| `sha` | required | The SHA of the commit to find the PR number for. | |
| `github-repository` | required | The GitHub repository to search for the PR in. | |
| `retry-delay` | optional | The delay in seconds between retries. | 120 |
| `max-attempts` | optional | The maximum number of attempts to find the PR number. | 5 |

## Outputs

| Output variable | Description |
| --------------- | -------------- |
| `number` | The PR number. |

## Example

```yaml
name: Publish Results
on:
workflow_call:
jobs:
publish-results:
runs-on: ubuntu-latest
steps:
- uses: tektronix/python-package-ci-cd/actions/[email protected]
id: fetch-pr-number
with:
sha: ${{ github.event.workflow_run.head_sha }} # required
github-repository: ${{ github.repository }} # required
retry-delay: 120 # optional
max-attempts: 5 # optional
- name: Echo PR Number
run: |
echo "PR Number: ${{ steps.fetch-pr-number.outputs.number }}"
```
1 change: 1 addition & 0 deletions doc_config/known_words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ codecov
codeql
create_unique_testpypi_version
dependabot
fetch_pr_number
find_unreleased_changelog_items
gh
ghaction
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,5 @@ nav:
- actions/create_unique_testpypi_version/readme.md
- actions/find_unreleased_changelog_items/readme.md
- actions/update_development_dependencies/readme.md
- actions/fetch_pr_number/readme.md
- Contributing: [CONTRIBUTING.md, CODE_OF_CONDUCT.md, LICENSE.md]

0 comments on commit 2ae3d4d

Please sign in to comment.