Skip to content

Commit 971ace2

Browse files
committed
Merge remote-tracking branch 'origin/main' into my-contribution
2 parents e9e97c8 + 2df5344 commit 971ace2

1,404 files changed

Lines changed: 164548 additions & 44606 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/CODEOWNERS

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
@reflex-dev/reflex-team
1+
* @reflex-dev/reflex-team
2+
3+
/docs/ @Alek99 @reflex-dev/reflex-team
4+
/README.md @Alek99 @reflex-dev/reflex-team
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
name: Documentation
3+
about: Report a problem with the docs at reflex.dev/docs
4+
title: ""
5+
labels: documentation
6+
assignees: ""
7+
---
8+
9+
**Page**
10+
Path:
11+
12+
**What's wrong?**
13+
A clear description of the issue (typo, missing info, broken example, etc.).
14+
15+
**Suggested fix (optional)**
16+
If you have a suggestion for how to improve the page, share it here.
17+
18+
**Screenshots (optional)**
19+
If applicable, add screenshots to help explain.

.github/codeql-config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
paths:
22
- .github
33
- reflex
4-
- reflex/.templates
4+
- packages
55
paths-ignore:
66
- "**/tests/**"
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
: "${PKG:?}"
5+
6+
LATEST=$(git tag -l "${PKG}-v*" | sed "s/^${PKG}-v//" | sort -V | tail -1)
7+
if [ -z "$LATEST" ]; then
8+
NEXT="0.0.1"
9+
else
10+
IFS='.' read -r MAJOR MINOR PATCH <<< "$LATEST"
11+
NEXT="${MAJOR}.${MINOR}.$((PATCH + 1))"
12+
fi
13+
14+
echo "version=$NEXT" >> "$GITHUB_OUTPUT"
15+
echo "tag=${PKG}-v${NEXT}" >> "$GITHUB_OUTPUT"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
: "${TAG:?}"
5+
: "${PKG:?}"
6+
: "${VERSION:?}"
7+
: "${GH_TOKEN:?}"
8+
: "${GITHUB_SHA:?}"
9+
10+
gh release create "$TAG" \
11+
--title "$PKG@$VERSION" \
12+
--notes "Automated release for $PKG v$VERSION" \
13+
--target "$GITHUB_SHA" \
14+
--latest=false
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
: "${EVENT_NAME:?}"
5+
6+
if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
7+
: "${DISPATCH_PACKAGE:?}"
8+
printf 'packages=["%s"]\n' "$DISPATCH_PACKAGE" >> "$GITHUB_OUTPUT"
9+
exit 0
10+
fi
11+
12+
PACKAGES=()
13+
for pkg in reflex-components-internal reflex-site-shared; do
14+
if git diff --name-only HEAD~1 HEAD -- "packages/$pkg/" | grep -q .; then
15+
PACKAGES+=("\"$pkg\"")
16+
fi
17+
done
18+
19+
JOINED=$(IFS=,; echo "${PACKAGES[*]:-}")
20+
echo "packages=[$JOINED]" >> "$GITHUB_OUTPUT"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
: "${TAG:?}"
5+
: "${GH_TOKEN:?}"
6+
7+
gh workflow run publish.yml -f tag="$TAG"
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
: "${TAG:?}"
5+
: "${PKG:?}"
6+
: "${VERSION:?}"
7+
: "${ACTION:?}"
8+
: "${GH_TOKEN:?}"
9+
: "${GITHUB_SHA:?}"
10+
11+
ARGS=(--title "$PKG@$VERSION" --notes "Dispatch release for $PKG v$VERSION (action=$ACTION)" --target "$GITHUB_SHA")
12+
if [[ "$ACTION" == release-* ]]; then
13+
if [[ "$PKG" != "reflex" ]]; then
14+
ARGS+=(--latest=false)
15+
fi
16+
else
17+
ARGS+=(--prerelease --latest=false)
18+
fi
19+
20+
gh release create "$TAG" "${ARGS[@]}"
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
declare -A MAP=(
5+
[hatch_reflex_pyi]=hatch-reflex-pyi
6+
[reflex_base]=reflex-base
7+
[reflex_components_code]=reflex-components-code
8+
[reflex_components_core]=reflex-components-core
9+
[reflex_components_dataeditor]=reflex-components-dataeditor
10+
[reflex_components_gridjs]=reflex-components-gridjs
11+
[reflex_components_lucide]=reflex-components-lucide
12+
[reflex_components_markdown]=reflex-components-markdown
13+
[reflex_components_moment]=reflex-components-moment
14+
[reflex_components_plotly]=reflex-components-plotly
15+
[reflex_components_radix]=reflex-components-radix
16+
[reflex_components_react_player]=reflex-components-react-player
17+
[reflex_components_recharts]=reflex-components-recharts
18+
[reflex_components_sonner]=reflex-components-sonner
19+
[reflex_docgen]=reflex-docgen
20+
[reflex_hosting_cli]=reflex-hosting-cli
21+
)
22+
ORDER=(hatch_reflex_pyi reflex_base reflex_components_code reflex_components_core reflex_components_dataeditor reflex_components_gridjs reflex_components_lucide reflex_components_markdown reflex_components_moment reflex_components_plotly reflex_components_radix reflex_components_react_player reflex_components_recharts reflex_components_sonner reflex_docgen reflex_hosting_cli)
23+
24+
PACKAGES=()
25+
for key in "${ORDER[@]}"; do
26+
if [[ "${!key:-false}" == "true" ]]; then
27+
PACKAGES+=("\"${MAP[$key]}\"")
28+
fi
29+
done
30+
31+
if [[ ${#PACKAGES[@]} -eq 0 ]]; then
32+
echo "Error: select at least one package"
33+
exit 1
34+
fi
35+
36+
JOINED=$(IFS=,; echo "${PACKAGES[*]}")
37+
echo "packages=[$JOINED]" >> "$GITHUB_OUTPUT"
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
# /// script
2+
# requires-python = ">=3.10"
3+
# dependencies = ["packaging"]
4+
# ///
5+
"""Plan the next version for each selected package.
6+
7+
Reads PACKAGES_JSON and ACTION from env, computes the next version per package
8+
using packaging.Version, writes a markdown summary to GITHUB_STEP_SUMMARY and a
9+
JSON array to GITHUB_OUTPUT for the release matrix.
10+
"""
11+
12+
from __future__ import annotations
13+
14+
import json
15+
import operator
16+
import os
17+
import pathlib
18+
import subprocess
19+
import sys
20+
from typing import NoReturn
21+
22+
from packaging.version import InvalidVersion, Version
23+
24+
ACTIONS: dict[str, tuple[str, str | None]] = {
25+
"new-prerelease-patch": ("new-prerelease", "patch"),
26+
"new-prerelease-minor": ("new-prerelease", "minor"),
27+
"new-prerelease-major": ("new-prerelease", "major"),
28+
"continued-prerelease": ("continued-prerelease", None),
29+
"release-from-prerelease": ("release", "from-prerelease"),
30+
"release-post": ("release", "post"),
31+
"release-patch": ("release", "patch"),
32+
"release-minor": ("release", "minor"),
33+
"release-major": ("release", "major"),
34+
}
35+
36+
37+
def fail(message: str) -> NoReturn:
38+
"""Print to stderr and exit 1."""
39+
sys.stderr.write(f"Error: {message}\n")
40+
sys.exit(1)
41+
42+
43+
def pick_latest(prefix: str) -> str | None:
44+
"""Return the largest PEP 440 tag under prefix (prefix stripped), or None.
45+
46+
Args:
47+
prefix: Tag prefix, e.g. ``v`` or ``reflex-base-v``.
48+
"""
49+
raw = subprocess.check_output(["git", "tag", "-l", f"{prefix}*"], text=True)
50+
pairs: list[tuple[Version, str]] = []
51+
for line in raw.splitlines():
52+
tag = line.removeprefix(prefix).strip()
53+
if not tag:
54+
continue
55+
try:
56+
pairs.append((Version(tag), tag))
57+
except InvalidVersion:
58+
continue
59+
if not pairs:
60+
return None
61+
_, original = max(pairs, key=operator.itemgetter(0))
62+
return original
63+
64+
65+
def next_version(latest: str | None, action: str, pkg: str) -> str:
66+
"""Compute the next version for pkg given action and latest.
67+
68+
Args:
69+
latest: Current latest version string, or None if the package has no prior tags.
70+
action: One of the keys in ACTIONS.
71+
pkg: Package name, used for error messages.
72+
73+
Returns:
74+
The next version string.
75+
"""
76+
mode, sub = ACTIONS[action]
77+
78+
if latest is None:
79+
major = minor = patch = alpha_n = post_n = 0
80+
is_alpha = False
81+
else:
82+
ver = Version(latest)
83+
major, minor, patch = ver.major, ver.minor, ver.micro
84+
is_alpha = ver.pre is not None and ver.pre[0] == "a"
85+
alpha_n = ver.pre[1] if is_alpha and ver.pre is not None else 0
86+
post_n = ver.post or 0
87+
88+
display = latest if latest is not None else "<none>"
89+
90+
if mode == "new-prerelease":
91+
if sub == "patch":
92+
return f"{major}.{minor}.{patch + 1}a1"
93+
if sub == "minor":
94+
return f"{major}.{minor + 1}.0a1"
95+
return f"{major + 1}.0.0a1"
96+
97+
if mode == "continued-prerelease":
98+
if not is_alpha:
99+
fail(
100+
f"continued-prerelease requires latest to be an alpha; "
101+
f"latest for {pkg} is {display!r}"
102+
)
103+
return f"{major}.{minor}.{patch}a{alpha_n + 1}"
104+
105+
if sub == "from-prerelease":
106+
if not is_alpha:
107+
fail(
108+
f"release-from-prerelease requires latest to be an alpha; "
109+
f"latest for {pkg} is {display!r}"
110+
)
111+
return f"{major}.{minor}.{patch}"
112+
if sub == "post":
113+
if latest is None:
114+
fail(f"release-post requires an existing release; no tags for {pkg}")
115+
if is_alpha:
116+
fail(
117+
f"release-post cannot follow an alpha; latest for {pkg} is {display!r}"
118+
)
119+
return f"{major}.{minor}.{patch}.post{post_n + 1}"
120+
if sub == "patch":
121+
return f"{major}.{minor}.{patch + 1}"
122+
if sub == "minor":
123+
return f"{major}.{minor + 1}.0"
124+
return f"{major + 1}.0.0"
125+
126+
127+
def tag_exists(tag: str) -> bool:
128+
"""Return whether a local git tag exists."""
129+
return (
130+
subprocess.run(
131+
["git", "rev-parse", "-q", "--verify", f"refs/tags/{tag}"],
132+
capture_output=True,
133+
check=False,
134+
).returncode
135+
== 0
136+
)
137+
138+
139+
def main() -> None:
140+
"""Entry point."""
141+
action = os.environ["ACTION"]
142+
packages_json = os.environ["PACKAGES_JSON"]
143+
github_output = os.environ["GITHUB_OUTPUT"]
144+
github_step_summary = os.environ["GITHUB_STEP_SUMMARY"]
145+
146+
if action not in ACTIONS:
147+
fail(f"unknown action '{action}'")
148+
149+
packages: list[str] = json.loads(packages_json)
150+
151+
summary_rows = [
152+
"## Release plan",
153+
"",
154+
f"Action: `{action}`",
155+
"",
156+
"| Package | Current | Next | Tag |",
157+
"|---------|---------|------|-----|",
158+
]
159+
releases: list[dict[str, str]] = []
160+
161+
for pkg in packages:
162+
tag_prefix = "v" if pkg == "reflex" else f"{pkg}-v"
163+
current = pick_latest(tag_prefix)
164+
next_ver = next_version(current, action, pkg)
165+
tag = f"{tag_prefix}{next_ver}"
166+
167+
if tag_exists(tag):
168+
fail(f"tag {tag} already exists")
169+
170+
display = current if current is not None else "<none>"
171+
summary_rows.append(f"| `{pkg}` | `{display}` | `{next_ver}` | `{tag}` |")
172+
releases.append({
173+
"package": pkg,
174+
"current": current or "",
175+
"next": next_ver,
176+
"tag": tag,
177+
})
178+
179+
# reflex is not independently releasable via dispatch: when reflex-base is
180+
# released, reflex is released alongside it with a matching version. The
181+
# publish workflow pins reflex-base exactly when building reflex.
182+
reflex_base_release = next(
183+
(r for r in releases if r["package"] == "reflex-base"), None
184+
)
185+
if reflex_base_release is not None:
186+
reflex_version = reflex_base_release["next"]
187+
reflex_tag = f"v{reflex_version}"
188+
if tag_exists(reflex_tag):
189+
fail(f"tag {reflex_tag} already exists")
190+
current_reflex = pick_latest("v")
191+
display = current_reflex if current_reflex is not None else "<none>"
192+
summary_rows.append(
193+
f"| `reflex` | `{display}` | `{reflex_version}` | `{reflex_tag}` |"
194+
)
195+
releases.append({
196+
"package": "reflex",
197+
"current": current_reflex or "",
198+
"next": reflex_version,
199+
"tag": reflex_tag,
200+
})
201+
202+
with pathlib.Path(github_step_summary).open("a") as f:
203+
f.write("\n".join(summary_rows) + "\n")
204+
with pathlib.Path(github_output).open("a") as f:
205+
f.write(f"releases={json.dumps(releases)}\n")
206+
207+
208+
if __name__ == "__main__":
209+
main()

0 commit comments

Comments
 (0)