Skip to content

Commit 017dafb

Browse files
author
github-actions
committed
[BUILD]: aad6b3d39980c7fa3139a29b6fadccce1d2c5a58
1 parent 2000bc4 commit 017dafb

File tree

20 files changed

+380
-183
lines changed

20 files changed

+380
-183
lines changed

.github/scripts/push-to-repo.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/bin/bash
2+
3+
# Get arguments
4+
EXCHANGE_NAME=$1
5+
API_TOKEN=$2
6+
GITHUB_SHA=$3
7+
8+
# Clone and push to the repo
9+
TEMP_DIR=$(mktemp -d)
10+
TEMP_DIR_GIT="$TEMP_DIR/$EXCHANGE_NAME-python"
11+
echo "Cloning $EXCHANGE_NAME-python repository into $TEMP_DIR_GIT"
12+
git clone https://x-access-token:$API_TOKEN@github.com/ccxt/$EXCHANGE_NAME-python.git $TEMP_DIR_GIT
13+
# at first, clean th directory (except .git directory) and copy all files
14+
echo "Clone finished"
15+
rm -rf $TEMP_DIR_GIT/*
16+
rm -rf $TEMP_DIR_GIT/.github/*
17+
rsync -av --info=progress2 --info=name0 --exclude='.git/' --exclude='tmp/' --exclude='build/ccxt/' ./ $TEMP_DIR_GIT
18+
rm -f $TEMP_DIR_GIT/.github/workflows/transfer-all.yml && rm -f $TEMP_DIR_GIT/.github/workflows/transfer-exchange.yml
19+
cd $TEMP_DIR_GIT
20+
echo $EXCHANGE_NAME > exchange_name
21+
git config user.name github-actions
22+
git config user.email github-actions@github.com
23+
git add .
24+
rm -f README.md
25+
(git commit -m "[BUILD]: $GITHUB_SHA" && git push origin main --force) || echo "No changes to commit"

.github/scripts/pushback.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/bash
2+
3+
git config --local user.email "action@github.com"
4+
git config --local user.name "GitHub Action"
5+
git add README.md
6+
git commit -m "Update README with exchange repository links" || echo "No changes to commit"
7+
git push
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: build
2+
on:
3+
push:
4+
branches:
5+
- main
6+
7+
jobs:
8+
build_for_pypi:
9+
if: ${{ github.event.repository.name != 'ccxt-python-single-exchange' && contains(github.event.head_commit.message, '[BUILD]') }}
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout code
13+
uses: actions/checkout@v4
14+
with:
15+
ref: ${{ github.ref }}
16+
- name: Install npm
17+
uses: actions/setup-node@v4
18+
with:
19+
node-version: '22'
20+
- name: Install dependencies
21+
run: |
22+
cd build
23+
npm install typescript
24+
npm install tsx
25+
- name: Build
26+
run: |
27+
cd build
28+
# get repository name and it's first word before hyphen and pass that as argument
29+
REPO_NAME=$(echo ${{ github.repository }} | cut -d'/' -f2 | cut -d'-' -f1)
30+
npm run build -- $REPO_NAME
31+
32+
- name: Commit and push changes
33+
run: |
34+
chmod +x .github/scripts/pushback.sh
35+
.github/scripts/pushback.sh
36+
37+
- name: Set up Python
38+
uses: actions/setup-python@v4
39+
with:
40+
python-version: '3.x'
41+
42+
- name: Install dependencies
43+
run: |
44+
python -m pip install --upgrade pip
45+
pip install build twine
46+
47+
- name: Build
48+
env:
49+
PYPI_API_SECRET: ${{ secrets.PYPI_API_SECRET }}
50+
run: |
51+
cd build
52+
npm run pypi-publish
53+
54+
- name: Upload to PyPI
55+
run: |
56+
cd ./temp_pypi
57+
python -m twine upload dist/*
58+
env:
59+
TWINE_USERNAME: __token__
60+
TWINE_PASSWORD: ${{ secrets.PYPI_API_SECRET }}

.github/workflows/reusable.yml

Lines changed: 0 additions & 58 deletions
This file was deleted.

.github/workflows/transfer.yml

Lines changed: 0 additions & 15 deletions
This file was deleted.

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,3 @@ cython_debug/
174174

175175
build/ccxt
176176
/meta.json
177-
/name
178-
/examples
179-
/README.md

.vscode/launch.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,20 @@
1111
"program": "${file}",
1212
"console": "integratedTerminal"
1313
},
14+
{
15+
"name": "TSX: file",
16+
"type": "node",
17+
"request": "launch",
18+
"runtimeExecutable": "tsx",
19+
"program": "${file}",
20+
"console": "integratedTerminal",
21+
"internalConsoleOptions": "neverOpen",
22+
"skipFiles": [
23+
"<node_internals>/**",
24+
"node_modules/**"
25+
],
26+
"sourceMaps": true,
27+
},
1428
{
1529
"name": "TSX: build",
1630
"type": "node",

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# central repo for single exchanges
2+
3+
this is dev.repo, not meant to be used by end users.

build/build.ts

Lines changed: 24 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,11 @@
11
import * as fs from 'fs'
22
import path from 'path'
3-
import { fileURLToPath } from 'url';
4-
import { exec, execSync } from 'node:child_process';
5-
6-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
73

4+
import { argvs, sanitizePackageName, exchangeArgv, execSync, cp, capitalize, regexAll } from './utils';
85

9-
// ##################### helpers ##################### //
10-
11-
function cp(source: string, destination: string): void {
12-
// check if source is file or dir
13-
if (!fs.existsSync(source)) {
14-
throw new Error(`Source file/directory does not exist: ${source}`);
15-
}
16-
const stats = fs.statSync(source);
17-
if (stats.isFile()) {
18-
// get parent directory
19-
const parentDir = path.dirname(destination);
20-
// check if parent directory exists
21-
if (!fs.existsSync(parentDir)) {
22-
fs.mkdirSync(parentDir, { recursive: true });
23-
}
24-
fs.copyFileSync(source, destination);
25-
return;
26-
}
27-
if (!fs.existsSync(destination)) {
28-
fs.mkdirSync(destination, { recursive: true });
29-
}
30-
const files = fs.readdirSync(source);
31-
for (const file of files) {
32-
const srcPath = path.join(source, file);
33-
const destPath = path.join(destination, file);
34-
cp(srcPath, destPath);
35-
}
36-
}
37-
38-
function capitalize(str) {
39-
return str.charAt(0).toUpperCase() + str.slice(1);
40-
}
6+
import { fileURLToPath } from 'url';
7+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
418

42-
// ################################################### //
439

4410

4511

@@ -60,7 +26,7 @@ class build {
6026
this.init(exchange);
6127
}
6228

63-
async downloadRepo() {
29+
async downloadCcxtRepo() {
6430
try {
6531
execSync('rm -rf ccxt/', { stdio: 'ignore' });
6632
} catch (ex) {
@@ -69,7 +35,7 @@ class build {
6935
execSync ('git clone --depth 1 https://github.com/ccxt/ccxt.git');
7036
}
7137

72-
copyFiles (exchange:string): void {
38+
copyCcxtFiles (exchange:string): void {
7339
const sourceDir = this.sourceFolder + '/python/ccxt/';
7440
const copyList = [
7541
// exchange files
@@ -101,21 +67,11 @@ class build {
10167
}
10268
}
10369

104-
regexAll (text: string, array: any[]) {
105-
for (const i in array) {
106-
const regexValue = array[i][0]
107-
const flags = (typeof regexValue === 'string') ? 'g' : undefined
108-
const regex = new RegExp (regexValue, flags)
109-
text = text.replace (regex, array[i][1])
110-
}
111-
return text
112-
}
113-
11470
async cleanInitFile(filePath: string, async = false) {
11571
let fileContent = fs.readFileSync(filePath, 'utf8');
11672
for (const id of this.allExchangesList) {
11773
if (id !== this.exchange) {
118-
fileContent = this.regexAll (fileContent, [
74+
fileContent = regexAll (fileContent, [
11975
[ new RegExp(`from ccxt\.${id} import ${id}.+\n`), '' ],
12076
[ new RegExp(`from ccxt\.async_support\.${id} import ${id}.+\n`), '' ],
12177
[ new RegExp(`from ccxt\.pro\.${id} import ${id}.+\n`), '' ],
@@ -183,26 +139,31 @@ class build {
183139
fs.writeFileSync (__dirname + '/../meta.json', stringified);
184140
}
185141

186-
capitalize (str: string) {
187-
return str.charAt(0).toUpperCase() + str.slice(1);
188-
}
189-
190142
replaceGlobalRegexes (text: string, array: any[]) {
191143
let newText = text;
192-
newText = this.regexAll (newText, [
144+
newText = regexAll (newText, [
193145
['__exchangeName__', this.exchange],
194-
['__ExchangeName__', this.capitalize(this.exchange)],
146+
['__ExchangeName__', capitalize(this.exchange)],
195147
]);
148+
const otherStrings = {
149+
'__LINK_TO_OFFICIAL_EXCHANGE_DOCS__': 'https://ccxt.com',
150+
'__PYTHON_PACKAGE_NAME__': undefined,
151+
'__TEST_SYMBOL__': 'BTC/USDC',
152+
};
196153
const exchangeConfig = this.globalConfigs['exchanges'][this.exchange];
197-
for (const key in exchangeConfig) {
198-
newText = newText.replace(new RegExp(`${key}`, 'g'), exchangeConfig[key]);
154+
for (const key in otherStrings) {
155+
const defaultValue = otherStrings[key];
156+
let value = exchangeConfig[key] || defaultValue; // at first, read from config, if not, use default
157+
newText = newText.replace(new RegExp(`${key}`, 'g'), value);
199158
}
159+
const sanitized = sanitizePackageName (exchangeConfig['__PYTHON_PACKAGE_NAME__']);
160+
newText = newText.replace(new RegExp(`__PYTHON_PACKAGE_KEY__`, 'g'), sanitized);
200161
return newText;
201162
}
202163

203164
generateExamples () {
204165
const destinationDir = __dirname + `/../examples/`;
205-
cp (__dirname + '/sources/examples/', destinationDir);
166+
cp (__dirname + '/templates/examples/', destinationDir);
206167
// iterate through files and make replacements
207168
const files = fs.readdirSync(destinationDir);
208169
for (const file of files) {
@@ -215,17 +176,17 @@ class build {
215176

216177
generateReadme () {
217178
const destinationDir = __dirname + `/../README.md`;
218-
cp (__dirname + '/sources/README.md', destinationDir);
179+
cp (__dirname + '/templates/README.md', destinationDir);
219180
let fileContent = fs.readFileSync(destinationDir, 'utf8');
220181
fileContent = this.replaceGlobalRegexes(fileContent, []);
221182
fs.writeFileSync(destinationDir, fileContent);
222183
}
223184

224185
async init (exchange:string) {
225186
if (this.downloadAndDelete) {
226-
await this.downloadRepo ();
187+
await this.downloadCcxtRepo ();
227188
}
228-
this.copyFiles (exchange);
189+
this.copyCcxtFiles (exchange);
229190
await this.setAllExchangesList ();
230191
await this.creataPackageInitFile ();
231192

@@ -250,18 +211,5 @@ class build {
250211

251212

252213

253-
254-
const argvs = process.argv.slice(2);
255-
let exchange = argvs[0];
256-
if (!exchange || exchange.includes('--')) {
257-
const nameFile = __dirname + '/../name';
258-
if (fs.existsSync(nameFile)) {
259-
exchange = fs.readFileSync(nameFile, 'utf8').trim();
260-
}
261-
}
262-
if (!exchange) {
263-
console.error('Please input exchange name in a "name" file in the root of the project');
264-
process.exit(1);
265-
}
266214
const donwloadAndDelete = !argvs.includes('--nodownload');
267-
new build(exchange, donwloadAndDelete);
215+
new build(exchangeArgv, donwloadAndDelete);

0 commit comments

Comments
 (0)