Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/e2e_test_darwin_prebuilt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: E2E tests on Darwin MacOS (Prebuilt release)

on:
push:
# branches: [main]
pull_request:
workflow_dispatch:
schedule:
# Runs at 12am UTC
- cron: '0 0 * * *'

jobs:
e2e_tests:
strategy:
matrix:
# ref: https://github.com/actions/runner-images
os: [macos-13]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v5
with:
go-version: '^1.24.2' # The Go version to download (if necessary) and use.

- name: build vfox (MacOS)
run: |
git clone https://github.com/version-fox/vfox.git
cd vfox
go build -o vfox
chmod +x vfox
cp vfox /usr/local/bin

- name: add vfox-erlang plugin (Unix-like)
run: |
vfox -version
vfox add --source https://github.com/version-fox/vfox-erlang/archive/${GITHUB_REF}.zip erlang

- name: install Erlang/OTP by vfox-erlang plugin (Darwin prebuilt)
run: |
export USE_PREBUILT_OTP=true
vfox install erlang@26.2.3
vfox use -g erlang@26.2.3
eval "$(vfox activate bash)"
echo "===============PATH==============="
echo $PATH
echo "===============PATH==============="
cd assets
erlc hello.erl
erl -noshell -s hello hello_world -s init stop
1 change: 1 addition & 0 deletions .github/workflows/update_otp_versions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
cd assets
python -m pip install requests
python get_all_otp_versions.py
python get_macos_prebuilt_versions.py

- name: Push updated version file
run: |
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.idea
.tool-versions
*.beam
available.cache
available.cache
.available.cache
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,32 @@ You can reference the E2E test in in windows-2022: [.github/workflows/e2e_test_w

## install a prebuilt Erlang/OTP version

After vfox-erlang v1.1.0, you can also install a prebuilt Erlang/OTP version in Ubuntu linux system.
After vfox-erlang v1.1.0, you can also install a prebuilt Erlang/OTP version in Ubuntu linux system and MacOS.

**Before install, you must disable vfox search cache.** Reference: [https://vfox.lhan.me/guides/configuration.html#cache-settings](https://vfox.lhan.me/guides/configuration.html#cache-settings)

### Linux (Ubuntu)

This is an installation example in Bash Shell:

```shell
# install an available version, you can also a avaliable version in: https://bobs-list.kobrakai.de/
USE_PREBUILT_OTP="ubuntu-20.04" vfox search erlang
USE_PREBUILT_OTP="ubuntu-20.04" vfox install erlang@26.2.3
```

**USE_PREBUILT_OTP** var value for Linux is one of: ["ubuntu-14.04", "ubuntu-16.04", "ubuntu-18.04", "ubuntu-20.04", "ubuntu-22.04", "ubuntu-24.04"].

### MacOS

For MacOS, you can use prebuilt Erlang/OTP versions from [@erlef/otp_builds](https://github.com/erlef/otp_builds) by setting the `USE_PREBUILT_OTP` environment variable:

```shell
# install a prebuilt version for MacOS (automatically detects architecture)
USE_PREBUILT_OTP=true vfox search erlang
USE_PREBUILT_OTP=true vfox install erlang@26.2.3
```

**USE_PREBUILT_OTP** var value is one of: ["ubuntu-14.04", "ubuntu-16.04", "ubuntu-18.04", "ubuntu-20.04", "ubuntu-22.04", "ubuntu-24.04"].
**USE_PREBUILT_OTP** can be set to any non-empty value (e.g., "1", "true", "macos") to enable prebuilt mode.

Supported architectures: amd64, x86_64, arm64, aarch64. macOS uses a dedicated prebuilt version list that differs from the Ubuntu prebuilt versions.
112 changes: 102 additions & 10 deletions assets/get_all_otp_versions.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,116 @@
import json
import requests


# fetch version: -> https://api.github.com/repos/erlang/otp/tags?per_page=100&sort=pushed
# github api has rate limt: https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#list-repository-tags
# prefer use local version file
def update_all_version_from_github_api():
all_version = []
for page in range(1,10):
for page in range(1, 10):
url = f"https://api.github.com/repos/erlang/otp/tags?per_page=100&sort=pushed&page={page}"
response = requests.get(url)
data = response.json()
all_version = all_version + data
all_version.extend(data)
if response.status_code != 200:
print("Failed to fetch data from github api")
return

with open("erlang_otp_versions_from_gtihub_api.json", 'w', encoding="utf-8") as file:
with open(
"erlang_otp_versions_from_gtihub_api.json", "w", encoding="utf-8"
) as file:
json.dump(all_version, file, indent=4)


def get_all_prebuilt_version_from_bob():
# ALLOW_OS_RELEASE = ["ubuntu-14.04", "ubuntu-16.04", "ubuntu-18.04", "ubuntu-20.04", "ubuntu-22.04", "ubuntu-24.04"]
ALLOW_OS_RELEASE = ["ubuntu-20.04"]
all_version_info = []
for release in ALLOW_OS_RELEASE:
url = f"https://builds.hex.pm/builds/otp/{release}/builds.txt"
response = requests.get(url)
all_version_info = response.text.split("\n")
all_version_info.extend(response.text.split("\n"))

all_prebuilt_versions = []
for version in all_version_info:
if version.split(" ")[0]:
all_prebuilt_versions.append(version.split(" ")[0])
return all_prebuilt_versions


def get_macos_prebuilt_versions():
"""Fetch all available macOS prebuilt versions from erlef/otp_builds"""

# GitHub API URL for releases
api_url = "https://api.github.com/repos/erlef/otp_builds/releases"

all_versions = []
page = 1

try:
while True:
print(f"Fetching macOS prebuilt versions page {page}...")
url = f"{api_url}?page={page}&per_page=100"

response = requests.get(url)
if response.status_code != 200:
break

releases = response.json()
if not releases:
break

for release in releases:
tag_name = release["tag_name"]
assets = release["assets"]

# Check if there are macOS related assets
has_macos_assets = False
for asset in assets:
asset_name = asset["name"]
# Check if contains macOS related filename patterns
if any(
pattern in asset_name.lower()
for pattern in [
"macos",
"darwin",
"osx",
"aarch64-apple",
"x86_64-apple",
"arm64.tar.gz",
"amd64.tar.gz",
]
):
has_macos_assets = True
break

if has_macos_assets:
# Remove 'OTP-' prefix except for special versions like master-latest
processed_version = tag_name
if processed_version.startswith("OTP-"):
processed_version = processed_version[
4:
] # Remove 'OTP-' prefix
all_versions.append(processed_version)
print(f"Found macOS version: {tag_name} -> {processed_version}")

page += 1
# Limit maximum pages to avoid infinite loop
if page > 20:
break

except Exception as e:
print(f"Error fetching macOS prebuilt data: {e}")
return []

return all_versions


def get_all_version():
version_set = set()
with open("erlang_otp_versions_from_gtihub_api.json", 'r', encoding="utf-8") as file:
with open(
"erlang_otp_versions_from_gtihub_api.json", "r", encoding="utf-8"
) as file:
data = json.load(file)
for item in data:
if "OTP-" not in item["tarball_url"]:
Expand All @@ -44,16 +119,33 @@ def get_all_version():
version_set.add(version)
return version_set


if __name__ == "__main__":
update_all_version_from_github_api()
versions = list(get_all_version())
versions.sort(reverse=True)
# print(versions)
with open("versions.txt", 'w') as file:
with open("versions.txt", "w") as file:
for version in versions:
file.write(version + '\n')
with open("prebuilt_versions.txt", 'w') as file:
file.write(version + "\n")

# Generate prebuilt versions for Linux
with open("prebuilt_versions.txt", "w") as file:
prebuilt_versions = get_all_prebuilt_version_from_bob()
prebuilt_versions.sort(reverse=True)
for version in prebuilt_versions:
file.write(version + '\n')
file.write(version + "\n")

# Generate prebuilt versions for macOS
print("\nFetching macOS prebuilt versions...")
macos_versions = get_macos_prebuilt_versions()
if macos_versions:
macos_versions.sort(reverse=True)
with open("macos_prebuilt_versions.txt", "w", encoding="utf-8") as file:
for version in macos_versions:
file.write(version + "\n")
print(
f"Found {len(macos_versions)} macOS prebuilt versions, saved to macos_prebuilt_versions.txt"
)
else:
print("No macOS prebuilt versions found.")
99 changes: 99 additions & 0 deletions assets/macos_prebuilt_versions.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
master-latest
maint-latest
maint-27-latest
maint-26-latest
maint-25-latest
28.0.1
28.0-rc4
28.0-rc3
28.0-rc2
28.0-rc1
28.0
27.3.4.1
27.3.4
27.3.3
27.3.2
27.3.1
27.3
27.2.4
27.2.3
27.2.2
27.2.1
27.2
27.1.3
27.1.2
27.1.1
27.1
27.0.1
27.0-rc3
27.0-rc2
27.0-rc1
27.0
26.2.5.9
26.2.5.8
26.2.5.7
26.2.5.6
26.2.5.5
26.2.5.4
26.2.5.3
26.2.5.2
26.2.5.13
26.2.5.12
26.2.5.11
26.2.5.10
26.2.5.1
26.2.5
26.2.4
26.2.3
26.2.2
26.2.1
26.2
26.1.2
26.1.1
26.1
26.0.2
26.0.1
26.0-rc3
26.0-rc2
26.0-rc1
26.0
25.3.2.9
25.3.2.8
25.3.2.7
25.3.2.6
25.3.2.5
25.3.2.4
25.3.2.3
25.3.2.21
25.3.2.20
25.3.2.2
25.3.2.19
25.3.2.18
25.3.2.17
25.3.2.16
25.3.2.15
25.3.2.14
25.3.2.13
25.3.2.12
25.3.2.11
25.3.2.10
25.3.2.1
25.3.2
25.3.1
25.3
25.2.3
25.2.2
25.2.1
25.2
25.1.2.1
25.1.2
25.1.1
25.1
25.0.4
25.0.3
25.0.2
25.0.1
25.0-rc3
25.0-rc2
25.0-rc1
25.0
Loading