Skip to content

Commit 91b620e

Browse files
committed
copy in workflows from pychangeset
1 parent f3157f7 commit 91b620e

File tree

3 files changed

+289
-0
lines changed

3 files changed

+289
-0
lines changed

.github/workflows/changesets.yml

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
name: Changesets
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
workflow_dispatch:
8+
9+
jobs:
10+
changesets:
11+
name: Create or Update Release PR
12+
runs-on: ubuntu-latest
13+
permissions:
14+
contents: write
15+
pull-requests: write
16+
17+
steps:
18+
- name: Checkout main branch
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
token: ${{ secrets.GITHUB_TOKEN }}
23+
24+
- name: Set up Python
25+
uses: actions/setup-python@v5
26+
with:
27+
python-version: "3.13"
28+
29+
- name: Install uv
30+
uses: astral-sh/setup-uv@v2
31+
32+
- name: Check for changesets
33+
id: check_changesets
34+
run: |
35+
if ls .changeset/*.md 2>/dev/null | grep -v README.md > /dev/null; then
36+
echo "has_changesets=true" >> $GITHUB_OUTPUT
37+
else
38+
echo "has_changesets=false" >> $GITHUB_OUTPUT
39+
fi
40+
41+
- name: Get PR metadata
42+
if: steps.check_changesets.outputs.has_changesets == 'true'
43+
id: pr_metadata
44+
run: |
45+
# Get the merge commit info
46+
COMMIT_SHA="${{ github.sha }}"
47+
echo "COMMIT_SHA=$COMMIT_SHA" >> $GITHUB_ENV
48+
49+
# Try to extract PR info from commit message
50+
PR_NUMBER=$(git log -1 --pretty=%B | grep -oP '(?<=#)\d+' | head -1 || echo "")
51+
if [ -n "$PR_NUMBER" ]; then
52+
echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV
53+
54+
# Get PR author using GitHub API
55+
PR_AUTHOR=$(gh api repos/${{ github.repository }}/pulls/$PR_NUMBER --jq '.user.login' || echo "")
56+
echo "PR_AUTHOR=$PR_AUTHOR" >> $GITHUB_ENV
57+
fi
58+
env:
59+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
60+
61+
- name: Generate changelogs and PR description
62+
if: steps.check_changesets.outputs.has_changesets == 'true'
63+
run: |
64+
# Generate changelogs and PR description
65+
uvx changeset changelog --output-pr-description pr-description.md
66+
67+
# Save PR description for later use
68+
echo "PR_DESCRIPTION<<EOF" >> $GITHUB_ENV
69+
cat pr-description.md >> $GITHUB_ENV
70+
echo "EOF" >> $GITHUB_ENV
71+
rm pr-description.md
72+
73+
- name: Bump versions
74+
if: steps.check_changesets.outputs.has_changesets == 'true'
75+
run: |
76+
uvx changeset version --skip-changelog
77+
78+
- name: Commit changes
79+
if: steps.check_changesets.outputs.has_changesets == 'true'
80+
id: commit
81+
run: |
82+
git config user.name "github-actions[bot]"
83+
git config user.email "github-actions[bot]@users.noreply.github.com"
84+
85+
# Add all changes
86+
git add .
87+
88+
# Commit if there are changes
89+
if ! git diff --cached --quiet; then
90+
git commit -m "Version packages and update changelogs"
91+
echo "has_changes=true" >> $GITHUB_OUTPUT
92+
else
93+
echo "has_changes=false" >> $GITHUB_OUTPUT
94+
fi
95+
96+
- name: Force push to changeset branch
97+
if: steps.check_changesets.outputs.has_changesets == 'true' && steps.commit.outputs.has_changes == 'true'
98+
run: |
99+
# Force push to the changeset-release branch
100+
git push origin HEAD:changeset-release --force
101+
102+
- name: Create or update PR
103+
if: steps.check_changesets.outputs.has_changesets == 'true' && steps.commit.outputs.has_changes == 'true'
104+
uses: actions/github-script@v7
105+
with:
106+
script: |
107+
const { data: prs } = await github.rest.pulls.list({
108+
owner: context.repo.owner,
109+
repo: context.repo.repo,
110+
head: `${context.repo.owner}:changeset-release`,
111+
base: 'main',
112+
state: 'open'
113+
});
114+
115+
const prBody = process.env.PR_DESCRIPTION;
116+
const prTitle = '🚀 Release packages';
117+
118+
if (prs.length > 0) {
119+
// Update existing PR
120+
const pr = prs[0];
121+
await github.rest.pulls.update({
122+
owner: context.repo.owner,
123+
repo: context.repo.repo,
124+
pull_number: pr.number,
125+
title: prTitle,
126+
body: prBody
127+
});
128+
console.log(`Updated PR #${pr.number}`);
129+
} else {
130+
// Create new PR
131+
const { data: pr } = await github.rest.pulls.create({
132+
owner: context.repo.owner,
133+
repo: context.repo.repo,
134+
title: prTitle,
135+
body: prBody,
136+
head: 'changeset-release',
137+
base: 'main'
138+
});
139+
console.log(`Created PR #${pr.number}`);
140+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Check Changeset
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize]
6+
7+
jobs:
8+
check-changeset:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Checkout
12+
uses: actions/checkout@v4
13+
with:
14+
fetch-depth: 0
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v5
18+
with:
19+
python-version: "3.13"
20+
21+
- name: Install uv
22+
uses: astral-sh/setup-uv@v2
23+
24+
- name: Check for changeset
25+
run: |
26+
uvx changeset check-changeset

.github/workflows/release.yml

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
name: Release
2+
3+
on:
4+
pull_request:
5+
types: [closed]
6+
branches:
7+
- main
8+
9+
jobs:
10+
release:
11+
name: Release packages
12+
# Only run when changeset PR is merged
13+
if: github.event.pull_request.merged == true && github.event.pull_request.head.ref == 'changeset-release'
14+
runs-on: ubuntu-latest
15+
environment: pypi
16+
permissions:
17+
contents: write
18+
id-token: write # For PyPI trusted publishing
19+
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
with:
24+
fetch-depth: 0
25+
26+
- name: Set up Python
27+
uses: actions/setup-python@v5
28+
with:
29+
python-version: '3.13'
30+
31+
- name: Install uv
32+
uses: astral-sh/setup-uv@v2
33+
34+
- name: Build packages
35+
run: |
36+
# Find all packages with pyproject.toml
37+
for pyproject in $(find . -name "pyproject.toml" -not -path "./.venv/*" -not -path "./node_modules/*"); do
38+
dir=$(dirname "$pyproject")
39+
echo "Building package in $dir"
40+
(cd "$dir" && uv build)
41+
done
42+
43+
- name: Get version info
44+
id: versions
45+
run: |
46+
# Extract version info from PR body
47+
# This is a simplified version - you might want to make it more robust
48+
echo "Extracting version information..."
49+
50+
# For each package, get its version
51+
RELEASE_TAGS=""
52+
for pyproject in $(find . -name "pyproject.toml" -not -path "./.venv/*" -not -path "./node_modules/*"); do
53+
dir=$(dirname "$pyproject")
54+
# Extract package name and version
55+
PACKAGE_NAME=$(python -c "import tomllib; print(tomllib.load(open('$pyproject', 'rb'))['project']['name'])")
56+
PACKAGE_VERSION=$(python -c "import tomllib; print(tomllib.load(open('$pyproject', 'rb'))['project']['version'])")
57+
58+
# Add to release tags
59+
TAG="${PACKAGE_NAME}-v${PACKAGE_VERSION}"
60+
RELEASE_TAGS="${RELEASE_TAGS}${TAG} "
61+
62+
echo "Package: $PACKAGE_NAME @ $PACKAGE_VERSION"
63+
done
64+
65+
echo "release_tags=$RELEASE_TAGS" >> $GITHUB_OUTPUT
66+
67+
- name: Publish to PyPI
68+
run: |
69+
# Publish each package
70+
for pyproject in $(find . -name "pyproject.toml" -not -path "./.venv/*" -not -path "./node_modules/*"); do
71+
dir=$(dirname "$pyproject")
72+
echo "Publishing package in $dir"
73+
(cd "$dir" && uv publish)
74+
done
75+
76+
- name: Create git tags
77+
run: |
78+
git config user.name "github-actions[bot]"
79+
git config user.email "github-actions[bot]@users.noreply.github.com"
80+
81+
# Create tags for each package
82+
for pyproject in $(find . -name "pyproject.toml" -not -path "./.venv/*" -not -path "./node_modules/*"); do
83+
PACKAGE_NAME=$(python -c "import tomllib; print(tomllib.load(open('$pyproject', 'rb'))['project']['name'])")
84+
PACKAGE_VERSION=$(python -c "import tomllib; print(tomllib.load(open('$pyproject', 'rb'))['project']['version'])")
85+
TAG="${PACKAGE_NAME}-v${PACKAGE_VERSION}"
86+
87+
# Create and push tag
88+
git tag -a "$TAG" -m "Release $PACKAGE_NAME v$PACKAGE_VERSION"
89+
git push origin "$TAG"
90+
done
91+
92+
- name: Create GitHub releases
93+
uses: actions/github-script@v7
94+
with:
95+
script: |
96+
// Get the PR body which contains our changelog
97+
const prBody = context.payload.pull_request.body;
98+
99+
// Parse the PR body to extract package releases
100+
const releaseRegex = /## (.+)@(.+)\n([\s\S]*?)(?=\n## |$)/g;
101+
let match;
102+
103+
while ((match = releaseRegex.exec(prBody)) !== null) {
104+
const packageName = match[1];
105+
const version = match[2];
106+
const changelog = match[3].trim();
107+
const tag = `${packageName}-v${version}`;
108+
109+
try {
110+
await github.rest.repos.createRelease({
111+
owner: context.repo.owner,
112+
repo: context.repo.repo,
113+
tag_name: tag,
114+
name: `${packageName} v${version}`,
115+
body: changelog,
116+
draft: false,
117+
prerelease: false
118+
});
119+
console.log(`Created release for ${tag}`);
120+
} catch (error) {
121+
console.error(`Failed to create release for ${tag}:`, error);
122+
}
123+
}

0 commit comments

Comments
 (0)