From dcfe669df18761d33f6dfd29d0826f2787fbe924 Mon Sep 17 00:00:00 2001 From: Yuki Sawa Date: Mon, 6 Nov 2023 13:58:15 -0800 Subject: [PATCH] Generate GH Action CI automatically (#6) * add ci feat * clean * clean --- .github/workflows/release.yaml | 4 +- .pre-commit-config.yaml | 2 +- example/.github/workflows/ci.yaml | 83 ++++++++++++++++++++++++++++ example/pyproject.toml | 62 +++++++++++++++++++++ rustfmt.toml | 6 ++ src/python.rs | 59 ++++++-------------- templates/.github/workflows/ci.yaml | 85 +++++++++++++++++++++++++++++ 7 files changed, 256 insertions(+), 45 deletions(-) create mode 100644 example/.github/workflows/ci.yaml create mode 100644 example/pyproject.toml create mode 100644 rustfmt.toml create mode 100644 templates/.github/workflows/ci.yaml diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 457faee..f196992 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -44,8 +44,8 @@ jobs: with: path: | target - # key: ${{ runner.os }}-cargo-${{ hashFiles('Cargo.lock') }} - key: ${{ runner.os }}-cargo- + key: ${{ runner.os }}-cargo-${{ hashFiles('Cargo.lock') }} + # key: ${{ runner.os }}-cargo- restore-keys: | ${{ runner.os }}-cargo- diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8bfe459..efef512 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -109,7 +109,7 @@ repos: - javascript - yaml - markdown - exclude: templates/.pre-commit-config.yaml + exclude: templates/.pre-commit-config.yaml|templates/.github/workflows/ci.yaml ############################################################################# # Rust diff --git a/example/.github/workflows/ci.yaml b/example/.github/workflows/ci.yaml new file mode 100644 index 0000000..3e0f536 --- /dev/null +++ b/example/.github/workflows/ci.yaml @@ -0,0 +1,83 @@ +name: CI + +on: + pull_request: # Start the job on all PRs + branches: [master, main] + types: [synchronize, opened, reopened, ready_for_review] + push: # Start the job on all main branch push + branches: [master, main] + +jobs: + precommit: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: Cache pip dependencies + uses: actions/cache@v3 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip- + restore-keys: | + ${{ runner.os }}-pip- + + - name: Cache shfmt binary + uses: actions/cache@v3 + with: + path: /usr/local/bin/shfmt + # key: ${{ runner.os }}-shfmt-${{ env.SHFMT_VERSION }} + key: ${{ runner.os }}-shfmt- + restore-keys: | + ${{ runner.os }}-shfmt- + + - name: Cache Pre-Commit environments + uses: actions/cache@v3 + with: + path: ~/.cache/pre-commit + # key: ${{ runner.os }}-pc-${{ hashFiles('.pre-commit-config.yaml') }} + key: ${{ runner.os }}-pc- + restore-keys: | + ${{ runner.os }}-pc- + + - name: Install dependencies + run: | + python -m pip install pre-commit + pre-commit install + + - name: Install shfmt + run: | + SHFMT_VERSION="v3.7.0" + SHFMT_BIN="shfmt_${SHFMT_VERSION}_linux_amd64" + if [[ ! -f /usr/local/bin/shfmt ]]; then + wget -O shfmt "https://github.com/mvdan/sh/releases/download/${SHFMT_VERSION}/${SHFMT_BIN}" + chmod +x shfmt + sudo mv shfmt /usr/local/bin/ + fi + sudo apt-get install shellcheck + + - name: Run pre-commits + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + REPO_NAME=$(echo $GITHUB_REPOSITORY | sed 's/^.*\///') + DEFAULT_BRANCH=$(curl -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/repos/$GITHUB_REPOSITORY" | jq -r '.default_branch') + + git fetch + CUR_SHA=$(git log --pretty=tformat:"%H" -n1 . | tail -n1) + + echo "Default branch is $DEFAULT_BRANCH" + echo "Current SHA is $CUR_SHA" + + if [[ $GITHUB_REF == "refs/heads/$DEFAULT_BRANCH" ]]; then + pre-commit run --all + else + pre-commit run --from-ref origin/$DEFAULT_BRANCH --to-ref $CUR_SHA + fi diff --git a/example/pyproject.toml b/example/pyproject.toml new file mode 100644 index 0000000..797ef53 --- /dev/null +++ b/example/pyproject.toml @@ -0,0 +1,62 @@ +[tool.poetry] +name = "example" +version = "0.0.1" +description = "" +authors = [ + "My Name " +] +license = "" + +[build-system] +requires = ["poetry-core>=1.7.0"] +build-backend = "poetry.core.masonry.api" + +[tool.black] +line-length = 120 +skip-string-normalization = false +target-version = ['py310'] +include = '\.pyi?$' +exclude = ''' +/( + \.eggs + | \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | _build + | buck-out + | build + | dist +)/ +''' +color = true + +[tool.isort] +balanced_wrapping = true +include_trailing_comma = true +known_first_party = "example" +known_third_party = [ + "boto3", # Common for AWS + "django", # Common web framework, if used + "flask", # Common web framework, if used + "jinja2", # Common templating engine + "matplotlib", # Common for plotting + "numpy", # Common for numerical operations + "pandas", # Common for data manipulation + "pendulum", # Common for date time + "pytest", # Common for testing + "requests", # Common for HTTP requests + "sqlalchemy", # Common ORM for databases +] +multi_line_output = 3 +profile = "black" +line_length = 120 + +[tool.poetry.dependencies] +python = "^3.10" + +[tool.poetry.group.dev.dependencies] +pre-commit = ">=3.5.0" +pytest = "^7.3.1" +pytest-cov = "^4.1.0" diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..98b65b3 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,6 @@ +max_width = 120 +imports_granularity = "Crate" +group_imports = "StdExternalCrate" +imports_layout = "Horizontal" + +comment_width = 200 diff --git a/src/python.rs b/src/python.rs index 4274c50..c97e10e 100644 --- a/src/python.rs +++ b/src/python.rs @@ -44,6 +44,10 @@ struct Flake8 {} #[template(path = ".cpa/prettier.json", escape = "none")] struct Prettier {} +#[derive(Template)] +#[template(path = ".github/workflows/ci.yaml", escape = "none")] +struct GHWorkflowCI {} + pub fn setup_preset(mut preset: String, name: String, create: bool) { if preset == "python" { preset = "python3.10".to_string(); @@ -54,40 +58,26 @@ pub fn setup_preset(mut preset: String, name: String, create: bool) { } let _ = fs::create_dir_all(format!("{}/.cpa", prefix)); + + // Render Github Actions CI + let _ = fs::create_dir_all(format!("{}/.github/workflows", prefix)); + File::create(format!("{}/.github/workflows/ci.yaml", prefix)) + .and_then(|mut file| file.write_all(GHWorkflowCI {}.render().expect("Failed to render ci.yaml").as_bytes())) + .expect("Failed to create or write to ci.yaml"); + // Render .gitignore File::create(format!("{}/.gitignore", prefix)) - .and_then(|mut file| { - file.write_all( - GitIgnore {} - .render() - .expect("Failed to render .gitignore") - .as_bytes(), - ) - }) + .and_then(|mut file| file.write_all(GitIgnore {}.render().expect("Failed to render .gitignore").as_bytes())) .expect("Failed to create or write to .gitignore"); // Render Makefile File::create(format!("{}/Makefile", prefix)) - .and_then(|mut file| { - file.write_all( - Makefile {} - .render() - .expect("Failed to render Makefile") - .as_bytes(), - ) - }) + .and_then(|mut file| file.write_all(Makefile {}.render().expect("Failed to render Makefile").as_bytes())) .expect("Failed to create or write to Makefile"); // Render Dockerfile File::create(format!("{}/Dockerfile", prefix)) - .and_then(|mut file| { - file.write_all( - Dockerfile {} - .render() - .expect("Failed to render Dockerfile") - .as_bytes(), - ) - }) + .and_then(|mut file| file.write_all(Dockerfile {}.render().expect("Failed to render Dockerfile").as_bytes())) .expect("Failed to create or write to Dockerfile"); // Render main.py @@ -109,26 +99,12 @@ pub fn setup_preset(mut preset: String, name: String, create: bool) { // Render Flake8 conf File::create(format!("{}/.cpa/flake8.cfg", prefix)) - .and_then(|mut file| { - file.write_all( - Flake8 {} - .render() - .expect("Failed to render flake8.cfg") - .as_bytes(), - ) - }) + .and_then(|mut file| file.write_all(Flake8 {}.render().expect("Failed to render flake8.cfg").as_bytes())) .expect("Failed to create or write to flake8.cfg"); // Render Prettier conf File::create(format!("{}/.cpa/prettier.json", prefix)) - .and_then(|mut file| { - file.write_all( - Prettier {} - .render() - .expect("Failed to render prettier.json") - .as_bytes(), - ) - }) + .and_then(|mut file| file.write_all(Prettier {}.render().expect("Failed to render prettier.json").as_bytes())) .expect("Failed to create or write to prettier.json"); // Render Poetry conf @@ -147,8 +123,7 @@ pub fn setup_preset(mut preset: String, name: String, create: bool) { black_target_ver, }; let out_pyproj: String = pyproj.render().expect("Failed to render"); - let mut f_pyproj = - File::create(format!("{}/pyproject.toml", prefix)).expect("Could not create file"); + let mut f_pyproj = File::create(format!("{}/pyproject.toml", prefix)).expect("Could not create file"); f_pyproj .write_all(out_pyproj.as_bytes()) .expect("Could not write to file"); diff --git a/templates/.github/workflows/ci.yaml b/templates/.github/workflows/ci.yaml new file mode 100644 index 0000000..dd1d902 --- /dev/null +++ b/templates/.github/workflows/ci.yaml @@ -0,0 +1,85 @@ +{% raw %} +name: CI + +on: + pull_request: # Start the job on all PRs + branches: [master, main] + types: [synchronize, opened, reopened, ready_for_review] + push: # Start the job on all main branch push + branches: [master, main] + +jobs: + precommit: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: Cache pip dependencies + uses: actions/cache@v3 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip- + restore-keys: | + ${{ runner.os }}-pip- + + - name: Cache shfmt binary + uses: actions/cache@v3 + with: + path: /usr/local/bin/shfmt + # key: ${{ runner.os }}-shfmt-${{ env.SHFMT_VERSION }} + key: ${{ runner.os }}-shfmt- + restore-keys: | + ${{ runner.os }}-shfmt- + + - name: Cache Pre-Commit environments + uses: actions/cache@v3 + with: + path: ~/.cache/pre-commit + # key: ${{ runner.os }}-pc-${{ hashFiles('.pre-commit-config.yaml') }} + key: ${{ runner.os }}-pc- + restore-keys: | + ${{ runner.os }}-pc- + + - name: Install dependencies + run: | + python -m pip install pre-commit + pre-commit install + + - name: Install shfmt + run: | + SHFMT_VERSION="v3.7.0" + SHFMT_BIN="shfmt_${SHFMT_VERSION}_linux_amd64" + if [[ ! -f /usr/local/bin/shfmt ]]; then + wget -O shfmt "https://github.com/mvdan/sh/releases/download/${SHFMT_VERSION}/${SHFMT_BIN}" + chmod +x shfmt + sudo mv shfmt /usr/local/bin/ + fi + sudo apt-get install shellcheck + + - name: Run pre-commits + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + REPO_NAME=$(echo $GITHUB_REPOSITORY | sed 's/^.*\///') + DEFAULT_BRANCH=$(curl -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/repos/$GITHUB_REPOSITORY" | jq -r '.default_branch') + + git fetch + CUR_SHA=$(git log --pretty=tformat:"%H" -n1 . | tail -n1) + + echo "Default branch is $DEFAULT_BRANCH" + echo "Current SHA is $CUR_SHA" + + if [[ $GITHUB_REF == "refs/heads/$DEFAULT_BRANCH" ]]; then + pre-commit run --all + else + pre-commit run --from-ref origin/$DEFAULT_BRANCH --to-ref $CUR_SHA + fi +{% endraw %}