Skip to content

Commit f4385d1

Browse files
committed
Add crates.io publish workflow
1 parent 8e1859c commit f4385d1

2 files changed

Lines changed: 128 additions & 2 deletions

File tree

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
name: Publish crates
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
- '[0-9]*'
8+
workflow_dispatch:
9+
inputs:
10+
version:
11+
description: 'Version to publish. Defaults to the pushed tag name without leading v.'
12+
required: false
13+
type: string
14+
pd_vm_version:
15+
description: 'pd-vm dependency version override'
16+
required: false
17+
type: string
18+
19+
concurrency:
20+
group: publish-crates-${{ github.ref }}
21+
cancel-in-progress: false
22+
23+
jobs:
24+
publish:
25+
runs-on: ubuntu-latest
26+
permissions:
27+
contents: read
28+
env:
29+
PACKAGE_ORDER: rustscript-embedded
30+
PD_VM_VERSION: ${{ inputs.pd_vm_version || '0.22.2' }}
31+
steps:
32+
- name: Checkout rustscript-embedded
33+
uses: actions/checkout@v4
34+
with:
35+
path: rustscript-embedded
36+
- name: Checkout rustscript dependency
37+
uses: actions/checkout@v4
38+
with:
39+
repository: rustscript-lang/rustscript
40+
path: rustscript
41+
- name: Setup Rust
42+
uses: dtolnay/rust-toolchain@stable
43+
- name: Publish crates
44+
working-directory: rustscript-embedded
45+
env:
46+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
47+
INPUT_VERSION: ${{ inputs.version }}
48+
run: |
49+
set -euo pipefail
50+
if [[ -z "${CARGO_REGISTRY_TOKEN:-}" ]]; then
51+
echo "CARGO_REGISTRY_TOKEN is required" >&2
52+
exit 1
53+
fi
54+
version="${INPUT_VERSION:-}"
55+
if [[ -z "$version" ]]; then
56+
version="${GITHUB_REF_NAME#v}"
57+
fi
58+
if [[ -z "$version" ]]; then
59+
echo "version is required" >&2
60+
exit 1
61+
fi
62+
export PUBLISH_VERSION="$version"
63+
python3 - <<'PY'
64+
import os, re
65+
from pathlib import Path
66+
version = os.environ['PUBLISH_VERSION']
67+
dep_versions = {
68+
'rustscript-embedded': version,
69+
'pd-vm': os.environ.get('PD_VM_VERSION') or version,
70+
}
71+
dep_re = re.compile(r'^(\s*([A-Za-z0-9_-]+)\s*=\s*\{)(.*)(\}\s*)$')
72+
for path in Path('.').rglob('Cargo.toml'):
73+
lines = path.read_text().splitlines()
74+
out = []
75+
section = ''
76+
for line in lines:
77+
stripped = line.strip()
78+
if stripped.startswith('[') and stripped.endswith(']'):
79+
section = stripped
80+
if section in ('[workspace.package]', '[package]') and stripped.startswith('version = '):
81+
line = re.sub(r'version\s*=\s*"[^"]*"', f'version = "{version}"', line)
82+
match = dep_re.match(line)
83+
if match and 'path' in match.group(3):
84+
prefix, key, body, suffix = match.groups()
85+
package_match = re.search(r'package\s*=\s*"([^"]+)"', body)
86+
dep_name = package_match.group(1) if package_match else key
87+
dep_version = dep_versions.get(dep_name)
88+
if dep_version:
89+
if re.search(r'version\s*=\s*"[^"]*"', body):
90+
body = re.sub(r'version\s*=\s*"[^"]*"', f'version = "{dep_version}"', body)
91+
else:
92+
body = body.rstrip()
93+
if body and not body.endswith(','):
94+
body += ','
95+
body += f' version = "{dep_version}"'
96+
line = prefix + body + suffix
97+
out.append(line)
98+
path.write_text('\n'.join(out) + '\n')
99+
PY
100+
python3 - <<'PY'
101+
import urllib.error, urllib.request, os, subprocess, time, sys
102+
version = os.environ['PUBLISH_VERSION']
103+
packages = os.environ['PACKAGE_ORDER'].split()
104+
token = os.environ['CARGO_REGISTRY_TOKEN']
105+
def exists(crate, version):
106+
try:
107+
urllib.request.urlopen(f'https://crates.io/api/v1/crates/{crate}/{version}', timeout=20).read()
108+
return True
109+
except urllib.error.HTTPError as exc:
110+
if exc.code == 404:
111+
return False
112+
raise
113+
for package in packages:
114+
if exists(package, version):
115+
print(f'{package} {version} already published; skipping')
116+
continue
117+
for attempt in range(1, 19):
118+
print(f'publishing {package} {version}, attempt {attempt}')
119+
proc = subprocess.run(['cargo', 'publish', '-p', package, '--no-verify', '--allow-dirty', '--token', token], text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
120+
print(proc.stdout)
121+
if proc.returncode == 0 or exists(package, version):
122+
break
123+
if attempt == 18:
124+
sys.exit(proc.returncode)
125+
time.sleep(20)
126+
PY

‎Cargo.toml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
name = "rustscript-embedded"
33
version = "0.1.0"
44
edition = "2024"
5-
description = "Tiny embedded-facing RustScript runner examples with JIT disabled"
5+
description = "Embedded-facing RustScript runner examples with JIT disabled"
66
license = "MIT"
77

88
[dependencies]
9-
vm = { package = "pd-vm", path = "../rustscript", default-features = false, features = ["runtime"] }
9+
vm = { package = "pd-vm", path = "../rustscript", version = "0.1.0", default-features = false, features = ["runtime"] }
1010

1111
[profile.release]
1212
opt-level = "z"

0 commit comments

Comments
 (0)