Skip to content

Commit dfb4732

Browse files
authored
ci: switch releases to manual workflow_dispatch and pin reusable workflows
Run release.yml and pre_release.yml via workflow_dispatch so the runner stays on a branch. The reusable apify/workflows changelog job uses signed-commit, which runs git pull --rebase and fails in the detached-HEAD state that a tag/release trigger produces. - release.yml: manual stable release with release_type (auto/custom/patch/ minor/major) + custom_version inputs; serialized changelog -> GitHub release -> PyPI publish. - pre_release.yml: manual beta publish, PyPI-only (no git tag). - Both guard release_metadata to run only from main in the apify org. - run_code_checks.yml: pin reusable workflows to @v0.45.0 (was @main). - CONTRIBUTING.md: document the manual release flow.
1 parent 2f5c64a commit dfb4732

4 files changed

Lines changed: 141 additions & 53 deletions

File tree

.github/workflows/pre_release.yml

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,72 @@
11
name: Create a pre-release
22

33
on:
4-
# Trigger a beta version release (pre-release) on push to the main branch.
5-
push:
6-
branches:
7-
- main
8-
tags-ignore:
9-
- "**" # Ignore all tags to prevent duplicate builds when tags are pushed.
4+
# Trigger a beta version (pre-release) manually from the Actions tab.
5+
# Kept manual for now; may switch to automatic on push to main in the future.
6+
workflow_dispatch:
107

118
concurrency:
129
group: release
1310
cancel-in-progress: false
1411

1512
jobs:
1613
release_metadata:
17-
if: "!startsWith(github.event.head_commit.message, 'docs') && !startsWith(github.event.head_commit.message, 'ci') && startsWith(github.repository, 'apify/')"
1814
name: Prepare release metadata
1915
runs-on: ubuntu-latest
16+
permissions:
17+
contents: read
18+
pull-requests: read # git-cliff enhances release notes with PR links via GITHUB_TOKEN.
19+
issues: read # git-cliff enhances release notes with issue links via GITHUB_TOKEN.
2020
outputs:
2121
version_number: ${{ steps.release_metadata.outputs.version_number }}
2222
tag_name: ${{ steps.release_metadata.outputs.tag_name }}
2323
changelog: ${{ steps.release_metadata.outputs.changelog }}
2424
steps:
25+
- name: Verify running on main in the apify org
26+
if: github.ref != 'refs/heads/main' || !startsWith(github.repository, 'apify/')
27+
run: |
28+
echo "::error title=Wrong branch or repository::Pre-releases must run from main in an apify/ repository. ref=${{ github.ref }} repo=${{ github.repository }}"
29+
exit 1
30+
2531
- uses: apify/actions/git-cliff-release@v1.1.2
2632
id: release_metadata
2733
name: Prepare release metadata
2834
with:
2935
release_type: prerelease
3036
existing_changelog_path: CHANGELOG.md
3137

32-
# If github.ref points to a [ci skip] commit, this workflow won't run.
33-
# Otherwise, these checks will be launched from the `run_code_checks` workflow.
34-
wait_for_checks:
35-
name: Wait for code checks to pass
36-
runs-on: ubuntu-latest
37-
steps:
38-
- uses: lewagon/wait-on-check-action@v1.3.4
39-
with:
40-
ref: ${{ github.ref }}
41-
repo-token: ${{ secrets.GITHUB_TOKEN }}
42-
check-regexp: "(check|test)"
43-
ignore-checks: Wait for code checks to pass
44-
wait-interval: 5
38+
lint_check:
39+
name: Lint check
40+
uses: apify/workflows/.github/workflows/python_lint_check.yaml@v0.45.0
41+
with:
42+
python_versions: '["3.10", "3.11", "3.12", "3.13"]'
43+
install_command: uv pip install --system -e ".[dev]"
44+
lint_command: ruff check src tests && ruff format --check src tests
45+
46+
type_check:
47+
name: Type check
48+
uses: apify/workflows/.github/workflows/python_type_check.yaml@v0.45.0
49+
with:
50+
python_versions: '["3.10", "3.11", "3.12", "3.13"]'
51+
install_command: uv pip install --system -e ".[dev]"
52+
type_check_command: mypy src
53+
54+
unit_tests:
55+
name: Unit tests
56+
uses: apify/workflows/.github/workflows/python_unit_tests.yaml@v0.45.0
57+
with:
58+
python_versions: '["3.10", "3.11", "3.12", "3.13"]'
59+
operating_systems: '["ubuntu-latest"]'
60+
install_command: uv pip install --system -e ".[dev]"
61+
run_tests_command: pytest -q
4562

4663
update_changelog:
4764
name: Update changelog
48-
needs: [release_metadata, wait_for_checks]
49-
uses: apify/workflows/.github/workflows/python_bump_and_update_changelog.yaml@47c305bdd5647f56c224ef9257804493e0912698
65+
needs: [release_metadata, lint_check, type_check, unit_tests]
66+
# Bumps pyproject.toml to the next base version and overwrites CHANGELOG.md, then
67+
# commits and pushes to main via apify/actions/signed-commit (commit carries
68+
# [skip ci]). Works because workflow_dispatch from main keeps HEAD on the branch.
69+
uses: apify/workflows/.github/workflows/python_bump_and_update_changelog.yaml@v0.45.0
5070
with:
5171
version_number: ${{ needs.release_metadata.outputs.version_number }}
5272
changelog: ${{ needs.release_metadata.outputs.changelog }}
@@ -58,21 +78,25 @@ jobs:
5878
needs: [release_metadata, update_changelog]
5979
runs-on: ubuntu-latest
6080
permissions:
61-
contents: write
62-
id-token: write # Required for OIDC authentication.
81+
contents: read
82+
id-token: write # Required for OIDC authentication.
6383
environment:
6484
name: pypi
6585
url: https://pypi.org/project/strands-apify
6686
steps:
6787
- name: Prepare distribution
6888
uses: apify/actions/prepare-pypi-distribution@v1.1.2
6989
with:
90+
# is_prerelease="yes" makes prepare-pypi-distribution compute the next beta
91+
# number from PyPI and build X.Y.Zb<N>. Build from the post-bump commit so the
92+
# base version matches what update_changelog committed.
93+
ref: ${{ needs.update_changelog.outputs.changelog_commitish }}
7094
package_name: strands-apify
7195
is_prerelease: "yes"
7296
version_number: ${{ needs.release_metadata.outputs.version_number }}
73-
ref: ${{ needs.update_changelog.outputs.changelog_commitish }}
7497
install_command: uv pip install --system -e ".[dev]"
7598
build_command: hatch build
99+
76100
# Publishes the package to PyPI using PyPA official GitHub action with OIDC authentication.
77101
- name: Publish package to PyPI
78102
uses: pypa/gh-action-pypi-publish@release/v1

.github/workflows/release.yml

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,83 @@
1-
name: Publish release
1+
name: Create a release
22

33
on:
4-
release:
5-
types: [published]
4+
# Trigger a stable version release via GitHub's UI, with the ability to specify the type of release.
5+
workflow_dispatch:
6+
inputs:
7+
release_type:
8+
description: Release type
9+
required: true
10+
type: choice
11+
default: auto
12+
options:
13+
- auto
14+
- custom
15+
- patch
16+
- minor
17+
- major
18+
custom_version:
19+
description: The custom version to bump to (only for "custom" type)
20+
required: false
21+
type: string
22+
default: ""
623

724
concurrency:
825
group: release
926
cancel-in-progress: false
1027

1128
jobs:
1229
release_metadata:
13-
if: ${{ !github.event.release.prerelease }}
1430
name: Prepare release metadata
1531
runs-on: ubuntu-latest
32+
permissions:
33+
contents: read
34+
pull-requests: read # git-cliff enhances release notes with PR links via GITHUB_TOKEN.
35+
issues: read # git-cliff enhances release notes with issue links via GITHUB_TOKEN.
1636
outputs:
17-
version_number: ${{ steps.version.outputs.version_number }}
37+
version_number: ${{ steps.release_metadata.outputs.version_number }}
38+
tag_name: ${{ steps.release_metadata.outputs.tag_name }}
1839
changelog: ${{ steps.release_metadata.outputs.changelog }}
40+
release_notes: ${{ steps.release_metadata.outputs.release_notes }}
1941
steps:
20-
- name: Extract version from release tag
21-
id: version
42+
- name: Verify running on main in the apify org
43+
if: github.ref != 'refs/heads/main' || !startsWith(github.repository, 'apify/')
44+
run: |
45+
echo "::error title=Wrong branch or repository::Releases must run from main in an apify/ repository. ref=${{ github.ref }} repo=${{ github.repository }}"
46+
exit 1
47+
48+
- name: Validate inputs
49+
if: inputs.release_type == 'custom' && inputs.custom_version == ''
2250
run: |
23-
TAG_NAME="${{ github.event.release.tag_name }}"
24-
VERSION="${TAG_NAME#v}"
25-
echo "version_number=${VERSION}" >> $GITHUB_OUTPUT
51+
echo "::error title=Missing custom_version::release_type is 'custom' but custom_version is empty. Provide a custom version (e.g. 0.1.0) and re-run the workflow."
52+
exit 1
2653
2754
- uses: apify/actions/git-cliff-release@v1.1.2
2855
name: Prepare release metadata
2956
id: release_metadata
3057
with:
31-
release_type: custom
32-
custom_version: ${{ steps.version.outputs.version_number }}
58+
release_type: ${{ inputs.release_type }}
59+
custom_version: ${{ inputs.custom_version }}
3360
existing_changelog_path: CHANGELOG.md
3461

3562
lint_check:
36-
if: ${{ !github.event.release.prerelease }}
3763
name: Lint check
38-
uses: apify/workflows/.github/workflows/python_lint_check.yaml@47c305bdd5647f56c224ef9257804493e0912698
64+
uses: apify/workflows/.github/workflows/python_lint_check.yaml@v0.45.0
3965
with:
4066
python_versions: '["3.10", "3.11", "3.12", "3.13"]'
4167
install_command: uv pip install --system -e ".[dev]"
4268
lint_command: ruff check src tests && ruff format --check src tests
4369

4470
type_check:
45-
if: ${{ !github.event.release.prerelease }}
4671
name: Type check
47-
uses: apify/workflows/.github/workflows/python_type_check.yaml@47c305bdd5647f56c224ef9257804493e0912698
72+
uses: apify/workflows/.github/workflows/python_type_check.yaml@v0.45.0
4873
with:
4974
python_versions: '["3.10", "3.11", "3.12", "3.13"]'
5075
install_command: uv pip install --system -e ".[dev]"
5176
type_check_command: mypy src
5277

5378
unit_tests:
54-
if: ${{ !github.event.release.prerelease }}
5579
name: Unit tests
56-
uses: apify/workflows/.github/workflows/python_unit_tests.yaml@47c305bdd5647f56c224ef9257804493e0912698
80+
uses: apify/workflows/.github/workflows/python_unit_tests.yaml@v0.45.0
5781
with:
5882
python_versions: '["3.10", "3.11", "3.12", "3.13"]'
5983
operating_systems: '["ubuntu-latest"]'
@@ -63,33 +87,53 @@ jobs:
6387
update_changelog:
6488
name: Update changelog
6589
needs: [release_metadata, lint_check, type_check, unit_tests]
66-
uses: apify/workflows/.github/workflows/python_bump_and_update_changelog.yaml@47c305bdd5647f56c224ef9257804493e0912698
90+
uses: apify/workflows/.github/workflows/python_bump_and_update_changelog.yaml@v0.45.0
6791
with:
6892
version_number: ${{ needs.release_metadata.outputs.version_number }}
6993
changelog: ${{ needs.release_metadata.outputs.changelog }}
7094
secrets:
7195
APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }}
7296

97+
create_github_release:
98+
name: Create github release
99+
needs: [release_metadata, update_changelog]
100+
runs-on: ubuntu-latest
101+
permissions:
102+
contents: write # Required to create the tag and the GitHub release.
103+
env:
104+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
105+
steps:
106+
- name: Create release
107+
uses: softprops/action-gh-release@v2
108+
with:
109+
tag_name: ${{ needs.release_metadata.outputs.tag_name }}
110+
name: ${{ needs.release_metadata.outputs.version_number }}
111+
body: ${{ needs.release_metadata.outputs.release_notes }}
112+
target_commitish: ${{ needs.update_changelog.outputs.changelog_commitish }}
113+
73114
publish_to_pypi:
74115
name: Publish to PyPI
75-
needs: [release_metadata, update_changelog]
116+
needs: [release_metadata, update_changelog, create_github_release]
76117
runs-on: ubuntu-latest
77118
permissions:
78-
contents: write
79-
id-token: write
119+
contents: read
120+
id-token: write # Required for OIDC authentication.
80121
environment:
81122
name: pypi
82123
url: https://pypi.org/project/strands-apify
83124
steps:
84125
- name: Prepare distribution
85126
uses: apify/actions/prepare-pypi-distribution@v1.1.2
86127
with:
128+
# Build from the exact post-bump commit so the wheel's version metadata
129+
# matches the tag created by create_github_release.
87130
ref: ${{ needs.update_changelog.outputs.changelog_commitish }}
88131
package_name: strands-apify
89132
is_prerelease: ""
90133
version_number: ${{ needs.release_metadata.outputs.version_number }}
91134
install_command: uv pip install --system -e ".[dev]"
92135
build_command: hatch build
93136

137+
# Publishes the package to PyPI using PyPA official GitHub action with OIDC authentication.
94138
- name: Publish package to PyPI
95139
uses: pypa/gh-action-pypi-publish@release/v1

.github/workflows/run_code_checks.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,23 @@ on:
1010
jobs:
1111
lint_check:
1212
name: Lint check
13-
uses: apify/workflows/.github/workflows/python_lint_check.yaml@main
13+
uses: apify/workflows/.github/workflows/python_lint_check.yaml@v0.45.0
1414
with:
1515
python_versions: '["3.10", "3.11", "3.12", "3.13"]'
1616
install_command: uv pip install --system -e ".[dev]"
1717
lint_command: ruff check src tests && ruff format --check src tests
1818

1919
type_check:
2020
name: Type check
21-
uses: apify/workflows/.github/workflows/python_type_check.yaml@main
21+
uses: apify/workflows/.github/workflows/python_type_check.yaml@v0.45.0
2222
with:
2323
python_versions: '["3.10", "3.11", "3.12", "3.13"]'
2424
install_command: uv pip install --system -e ".[dev]"
2525
type_check_command: mypy src
2626

2727
unit_tests:
2828
name: Unit tests
29-
uses: apify/workflows/.github/workflows/python_unit_tests.yaml@main
29+
uses: apify/workflows/.github/workflows/python_unit_tests.yaml@v0.45.0
3030
with:
3131
python_versions: '["3.10", "3.11", "3.12", "3.13"]'
3232
operating_systems: '["ubuntu-latest"]'

CONTRIBUTING.md

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,29 @@ and the changelog is generated from these prefixes via [git-cliff](https://git-c
5454

5555
## Releases
5656

57-
Releases are cut from the
58-
[Actions tab](https://github.com/apify/strands-apify/actions/workflows/release.yml)
59-
by manually triggering the **Create a release** workflow.
57+
### Stable releases
58+
59+
1. Go to **Actions** > [**Create a release**](https://github.com/apify/strands-apify/actions/workflows/release.yml) > **Run workflow**.
60+
2. Pick a release type (`auto` recommended, or `patch`/`minor`/`major`/`custom`).
61+
3. Click **Run workflow**. The workflow runs checks, creates a tag + GitHub
62+
release, bumps `pyproject.toml` and `CHANGELOG.md`, and publishes to
63+
[PyPI](https://pypi.org/project/strands-apify/).
64+
65+
### Beta releases
66+
67+
Beta releases are also triggered manually, from **Actions** >
68+
[**Create a pre-release**](https://github.com/apify/strands-apify/actions/workflows/pre_release.yml)
69+
> **Run workflow**. The workflow runs the same checks as the stable release,
70+
bumps to the next beta version, updates the changelog, and publishes a
71+
`X.Y.Zb<N>` wheel to PyPI. (Automatic beta-on-push-to-main may be enabled
72+
later; for now both stable and beta releases are manual.)
73+
74+
### Notes
75+
76+
- Do not create tags or releases manually, the workflow handles both.
77+
- Release notes come from conventional commit subjects via git-cliff. You can
78+
edit the GitHub release body afterward if you want hand-curated notes.
79+
6080

6181
## Security issue notifications
6282

0 commit comments

Comments
 (0)