diff --git a/.coveragerc b/.coveragerc index 3834c598..b6ca4893 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,11 +1,7 @@ -# # This test directory for testing to simulate a Python library project structure. - [run] +branch = True parallel = True -relative_files = True source=./test_gh_workflow omit = */__init__.py - -#ignore_errors = True diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from .github/PULL_REQUEST_TEMPLATE/pull_request_template.md rename to .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/release-auto-flag.txt b/.github/release-auto-flag.txt new file mode 100644 index 00000000..f32a5804 --- /dev/null +++ b/.github/release-auto-flag.txt @@ -0,0 +1 @@ +true \ No newline at end of file diff --git a/.github/release-notes.md b/.github/release-notes.md new file mode 100644 index 00000000..753535fa --- /dev/null +++ b/.github/release-notes.md @@ -0,0 +1,17 @@ +### ๐ŸŽ‰๐ŸŽŠ๐Ÿพ New feature +
+ +1. Add new options about set up and run a sample HTTP server for testing if it needs in some testing scenario (_run_test_items_via_pytest.yaml_). + +### ๐Ÿ› โš™๏ธ๐Ÿ”ฉ **Breaking Change** +
+ +1. Integrate the feature about organizing and generating testing coverage reports into a reusable workflow. So workflow could be shorter and clear (_organize_and_generate_test_cov_reports.yaml_). +2. Integrate all the uploading test coverage report features into a reusable workflow (_upload_test_cov_report.yaml_). +3. Update document README. +4. Move the PR template to **_.github_** directory (for working finely). + +### โš’โš’๐Ÿ’ฃ **Bug Fix** +
+ +1. Fix the issue about uploading test coverage report cannot work at all. diff --git a/.github/release-title.md b/.github/release-title.md new file mode 100644 index 00000000..112843c8 --- /dev/null +++ b/.github/release-title.md @@ -0,0 +1 @@ +v2.0.0 - More short and clear <0001f9f9>๐Ÿป \ No newline at end of file diff --git a/.github/workflows/build_git-tag_and_create_github-release.yaml b/.github/workflows/build_git-tag_and_create_github-release.yaml new file mode 100644 index 00000000..8d2c629d --- /dev/null +++ b/.github/workflows/build_git-tag_and_create_github-release.yaml @@ -0,0 +1,100 @@ +############################################################################################## +# +# Workflow Description: +# Build a git tag on a specific commit in every git branch. And create GitHub release if current git branch is 'master'. +# +# Workflow input parameters: +# * General arguments: +# * project_type: Different project type would get the software version info in different way. +# * debug_mode: It would run the tasks as log message, doesn't essentially run feature if this option is true. +# * project_name: The project name. +# * software_version_format: The format of software version. +# +# Workflow running output: +# Yes, it has running result output. The output is the release version. +# +# * Workflow output: +# It would output the version which would be build as git tag and create GitHub release version title. +# * python_release_version: Python project release version info. +# * github-action_reusable_workflow_release_version: GitHub Action reusable workflow project release version info. +# +############################################################################################## + +name: Build git tag and create GitHub release with software version + +on: + workflow_call: + inputs: + project_type: + description: "Different project type would get the software version info in different way." + required: true + type: string # Option: python, github-action_reusable-workflow +# activate_git_event: +# description: "Which git event should activate the workflow." +# type: string +# required: false +# default: push + debug_mode: + description: "It would run the tasks as log message, doesn't essentially run feature if this option is true." + type: boolean + required: false + default: false + project_name: + description: "The project name." + type: string + required: false + software_version_format: + description: "The format of software version." + type: string + required: false + + outputs: + python_release_version: + description: "The version which would be build as git tag and create GitHub release version title." + value: ${{ jobs.build_git-tag_and_create_github-release.outputs.matrix_python }} + github-action_reusable_workflow_release_version: + description: "The version which would be build as git tag and create GitHub release version title." + value: ${{ jobs.build_git-tag_and_create_github-release.outputs.matrix_github_action_reusable_workflow }} + + +jobs: + build_git-tag_and_create_github-release: +# name: Build git tag and GitHub release if it needs + if: github.event_name == 'push' + runs-on: ubuntu-latest + outputs: + matrix_python: ${{ steps.python_release.outputs.release_type }} + matrix_github_action_reusable_workflow: ${{ steps.github_action_reusable_workflow_release.outputs.release_version }} + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Download shell script for checking input parameters + run: curl https://raw.githubusercontent.com/Chisanan232/GitHub-Action_Workflow-Template-Python/develop/scripts/ci/build_git-tag_or_create_github-release.sh --output ./scripts/ci/build_git-tag_or_create_github-release.sh + + # This flow for the project type is Python project + - name: Build git tag and create GitHub release for Python project + if: ${{ inputs.project_type == 'python-package' }} + id: python_release + run: | + release=$(bash ./scripts/ci/build_git-tag_or_create_github-release.sh ${{ inputs.project_type }} ${{ inputs.debug_mode }} ${{ inputs.project_name }} ${{ inputs.software_version_format }}) + echo "๐Ÿ“„ Release log: $release" + + release_type=$(echo "$release" | grep -E "\[Python\] \[Final Running Result\] ((Official\-Release)|(Pre\-Release))" | grep -E -o "((Official\-Release)|(Pre\-Release))") + echo "๐Ÿ Release Type: $release_type" + + echo "::set-output name=release_type::$(echo $release_type)" + + # This flow for the project type is GitHub Action reusable workflow + - name: Build git tag and create GitHub release for GitHub Action reusable workflow project + if: ${{ inputs.project_type == 'github-action-reusable-workflow' }} + id: github_action_reusable_workflow_release + run: | + release=$(bash ./scripts/ci/build_git-tag_or_create_github-release.sh ${{ inputs.project_type }} ${{ inputs.debug_mode }}) + echo "๐Ÿ“„ Release log: $release" + + release_version=$(echo "$release" | grep -E "\[GitHub Action - Reusable workflow\] \[Final Running Result\] Official-Release and version: ([0-9]{1,})" | grep -E -o "([0-9]{1,})") + echo "๐Ÿค– Release Version: $release_version" + + echo "::set-output name=release_version::$(echo $release_version)" + diff --git a/.github/workflows/ci-cd.yaml b/.github/workflows/ci-cd.yaml new file mode 100644 index 00000000..d5ace6e3 --- /dev/null +++ b/.github/workflows/ci-cd.yaml @@ -0,0 +1,52 @@ +name: GitHub Action reusable workflow build + +on: + push: + branches: + - "develop" + - "release" + - "master" + paths-ignore: + - ".gitcommitrules" + - ".gitignore" + - "LICENSE" + - "README.md" + + pull_request: + branches: + - "develop" + - "release" + paths-ignore: + - ".gitcommitrules" + - ".gitignore" + - "LICENSE" + - "README.md" + +jobs: + test_build_git-tag_and_create_github-release: +# name: Build git tag and GitHub release if it needs + uses: ./.github/workflows/build_git-tag_and_create_github-release.yaml + with: + project_type: github-action-reusable-workflow + debug_mode: false + + + test_deploy_as_new_branch: +# name: Create new git branch by the tagged commit + needs: test_build_git-tag_and_create_github-release + if: ${{ github.ref_name == 'master' && + github.event_name == 'push' && + needs.test_build_git-tag_and_create_github-release.outputs.github-action_reusable_workflow_release_version != 'Pre' }} + runs-on: ubuntu-latest + env: + RELEASE_TYPE: ${{ needs.test_build_git-tag_and_create_github-release.outputs.github-action_reusable_workflow_release_version }} + DEBUG_MODE: false + steps: + - uses: actions/checkout@v2 + + - name: Check it whether get the output of previous one job which has version info or not + run: bash scripts/ci/check_getting_output.sh + + - name: Create new git branch by the tagged commit + run: bash ./scripts/ci/deployment_new_version_workflow.sh $DEBUG_MODE + diff --git a/.github/workflows/organize_all_testing_coverage_reports_with_different_os_and_py_version.yaml b/.github/workflows/organize_all_testing_coverage_reports_with_different_os_and_py_version.yaml deleted file mode 100644 index 506004f9..00000000 --- a/.github/workflows/organize_all_testing_coverage_reports_with_different_os_and_py_version.yaml +++ /dev/null @@ -1,111 +0,0 @@ -############################################################################ -# -# Workflow Description: -# Organize all the testing coverage reports. (it would save reports by 'actions/upload-artifact@v3'). -# -# Workflow input parameters: -# * test_type: The testing type. In generally, it only has 2 options: 'unit-test' and 'integration-test'. -# * generate_xml_report_finally: Something, it only has 1 test type currently. So it could let this option -# to be 'true' than it would generate XML report finally to let uploading process to use it directly. -# -# Workflow running output: -# No, but it would save the testing coverage reports (coverage.xml) to provide after-process to organize and record. -# -############################################################################ - -name: Organize testing coverage reports as a testing coverage report - -on: - workflow_call: - inputs: - test_type: - description: "The testing type. In generally, it only has 2 options: 'unit-test' and 'integration-test'." - required: true - type: string - generate_xml_report_finally: - description: "Something, it only has 1 test type currently. So it could let this option to be 'true' than it would generate XML report finally to let uploading process to use it directly." - type: boolean - required: false - default: false - - -jobs: - organize_test_reports: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Download code coverage result file - uses: actions/download-artifact@v3 - with: - name: coverage - path: ./ - - - name: Setup Python 3.10 in Ubuntu OS - uses: actions/setup-python@v2 - with: - python-version: '3.10' - - - name: Install Python tool 'coverage' - run: | - python3 -m pip install --upgrade pip - pip3 install -U pip - pip3 install coverage - - - name: Combine all code coverage result files - run: coverage combine .coverage.* - - - name: Report testing coverage of project code - run: coverage report -m - - - name: Upload testing coverage report - uses: actions/upload-artifact@v3 - with: - name: project_testing_coverage_report_${{ inputs.test_type }} - path: .coverage - if-no-files-found: error - - generate_final_test_report: - if: ${{ inputs.generate_xml_report_finally == true }} -# if: inputs.generate_xml_report_finally == 'true' - needs: organize_test_reports - runs-on: ubuntu-latest - steps: - - name: Download code coverage result file - uses: actions/download-artifact@v3 - with: - name: project_testing_coverage_report_${{ inputs.test_type }} - path: ./ - - - name: General testing coverage report as XML format - run: coverage xml - - - name: Upload testing coverage report - uses: actions/upload-artifact@v3 - with: - name: final_project_testing_coverage_report - path: coverage.xml - if-no-files-found: error - - generate_test_type_report: - if: ${{ inputs.generate_xml_report_finally == false }} -# if: inputs.generate_xml_report_finally == 'false' - needs: organize_test_reports - runs-on: ubuntu-latest - steps: - - name: Download code coverage result file - uses: actions/download-artifact@v3 - with: - name: project_testing_coverage_report_${{ inputs.test_type }} - path: ./ - - - name: Rename the testing coverage report with test type - run: mv .coverage .coverage-${{ inputs.test_type }} - - - name: Upload testing coverage report - uses: actions/upload-artifact@v3 - with: - name: new_project_testing_coverage_report_${{ inputs.test_type }} - path: .coverage-${{ inputs.test_type }} - if-no-files-found: error diff --git a/.github/workflows/organize_all_testing_reports_with_different_test_type.yaml b/.github/workflows/organize_all_testing_reports_with_different_test_type.yaml deleted file mode 100644 index b2a84ef8..00000000 --- a/.github/workflows/organize_all_testing_reports_with_different_test_type.yaml +++ /dev/null @@ -1,64 +0,0 @@ -############################################################################ -# -# Workflow Description: -# Organize all the testing coverage reports. (it would save reports by 'actions/upload-artifact@v3'). -# -# Workflow input parameters: -# No input parameters. -# -# Workflow running output: -# No, but it would save the testing coverage reports (coverage.xml) to provide after-process to organize and record. -# -############################################################################ - -name: Organize all testing coverage reports, e.g., different runtime OS, as a final testing coverage report. - -on: - workflow_call: - - -jobs: - organize_and_generate_test_report: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Download code coverage result file - uses: actions/download-artifact@v3 - with: - name: new_project_testing_coverage_report_unit-test - path: ./ - - - name: Download code coverage result file - uses: actions/download-artifact@v3 - with: - name: new_project_testing_coverage_report_integration-test - path: ./ - - - name: Setup Python 3.10 in Ubuntu OS - uses: actions/setup-python@v2 - with: - python-version: '3.10' - - - name: Install Python tool 'coverage' - run: | - python -m pip install --upgrade pip - pip install -U pip - pip install coverage - - - name: Combine all code coverage result files - run: coverage combine .coverage-* - - - name: Report testing coverage of project code - run: coverage report -m - - - name: Generate testing coverage report as XML file - run: coverage xml - - - name: Upload testing coverage report - uses: actions/upload-artifact@v3 - with: - name: final_project_testing_coverage_report - path: coverage.xml - if-no-files-found: error diff --git a/.github/workflows/organize_and_generate_test_cov_reports.yaml b/.github/workflows/organize_and_generate_test_cov_reports.yaml new file mode 100644 index 00000000..882968b7 --- /dev/null +++ b/.github/workflows/organize_and_generate_test_cov_reports.yaml @@ -0,0 +1,81 @@ +################################################################################################################################### +# +# Workflow Description: +# Organize all the testing coverage reports. (it would save reports by 'actions/upload-artifact@v3'). +# +# Workflow input parameters: +# * test_type: The testing type. In generally, it only has 2 options: 'unit-test' and 'integration-test'. +# +# Workflow running output: +# No, but it would save the testing coverage reports (coverage.xml) to provide after-process to organize and record. +# +# * Upload-Artifact: +# * test_coverage_report: The handled test coverage report (.coverage file). It's file name format would be .coverage.. +# * test_coverage_xml_report: The handled test coverage report (.xml file). It's file name format would be coverage_.xml. +# +################################################################################################################################### + +name: Organize all testing coverage reports which be tested in many different runtime OS and Python version as a testing coverage report + +on: + workflow_call: + inputs: + test_type: + description: "The testing type. In generally, it only has 2 options: 'unit-test' and 'integration-test'." + required: true + type: string + + +jobs: + organize_and_generate_test_reports: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Download code coverage result file + uses: actions/download-artifact@v3 + with: + name: coverage + path: ./ + + - name: Setup Python 3.10 in Ubuntu OS + uses: actions/setup-python@v2 + with: + python-version: '3.10' + + - name: Install Python tool 'coverage' + run: | + python3 -m pip install --upgrade pip + pip3 install -U pip + pip3 install coverage + pip3 install codecov + pip3 install coveralls + + - name: Combine all testing code coverage result files with one specific test type + if: ${{ inputs.test_type == 'unit-test' || inputs.test_type == 'integration-test' }} + run: coverage combine --data-file=.coverage.${{ inputs.test_type }} .coverage.${{ inputs.test_type }}.* + + - name: Combine all testing code coverage result files with all test types + if: ${{ inputs.test_type == 'all-test' }} + run: coverage combine --data-file=.coverage.${{ inputs.test_type }} .coverage.* + + - name: Report testing coverage of project code + run: coverage report -m --data-file=.coverage.${{ inputs.test_type }} + + - name: General testing coverage report as XML format with ${{ inputs.test_type }} + run: coverage xml --data-file=.coverage.${{ inputs.test_type }} -o coverage_${{ inputs.test_type }}.xml + + - name: Upload testing coverage report (.coverage) + uses: actions/upload-artifact@v3 + with: + name: test_coverage_report + path: .coverage.${{ inputs.test_type }} + if-no-files-found: error + + - name: Upload testing coverage report (.xml) + uses: actions/upload-artifact@v3 + with: + name: test_coverage_xml_report + path: coverage_${{ inputs.test_type }}.xml + if-no-files-found: error diff --git a/.github/workflows/run_test_items_via_pytest.yaml b/.github/workflows/run_test_items_via_pytest.yaml index 6d640385..082274db 100644 --- a/.github/workflows/run_test_items_via_pytest.yaml +++ b/.github/workflows/run_test_items_via_pytest.yaml @@ -1,4 +1,4 @@ -############################################################################ +################################################################################################################################# # # Workflow Description: # Run testing by specific type with all test items via PyTest and generate its testing @@ -7,11 +7,21 @@ # Workflow input parameters: # * test_type: The testing type. In generally, it only has 2 options: 'unit-test' and 'integration-test'. # * all_test_items_paths: The target paths of test items under test. +# * setup_http_server: If it's true, it would set up and run HTTP server for testing. +# * http_server_host: The host IPv4 address of HTTP server. +# * http_server_port: The port number of HTTP server. +# * http_server_app_module: The module path of HTTP server. +# * http_server_enter_point: The object about the web application. +# * debug_mode: For debug, so it's matrix would one has os: ubuntu-22.04 & python-version: '3.10'. # # Workflow running output: # No, but it would save the testing coverage reports to provide after-process to organize and record. # -############################################################################ +# * Upload-Artifact: +# * coverage: The test coverage report which be generated by PyTest, and it's recorded after run test done. +# The file name format would be .coverage..- +# +################################################################################################################################# name: Run test items via PyTest @@ -26,16 +36,47 @@ on: description: "The target paths of test items under test." required: true type: string + setup_http_server: + description: "If it's true, it would set up and run HTTP server for testing." + type: boolean + required: false + default: false + http_server_host: + description: "The host IPv4 address of HTTP server." + type: string + required: false + default: 0.0.0.0 + http_server_port: + description: "The port number of HTTP server." + type: string + required: false + default: 12345 + http_server_app_module: + description: "The module path of HTTP server." + type: string + required: false + default: app + http_server_enter_point: + description: "The object about the web application." + type: string + required: false + default: app + debug_mode: + description: "For debug, so it's matrix would one has os: ubuntu-22.04 & python-version: '3.10'." + type: boolean + required: false + default: false jobs: run_test_items: + if: ${{ inputs.debug_mode == false }} runs-on: ${{ matrix.os }} strategy: matrix: python-version: [3.6,3.7,3.8,3.9,'3.10'] - os: [ubuntu-18.04,ubuntu-20.04,ubuntu-22.04, macos-10.15,macos-11,macos-12] + os: [ubuntu-18.04,ubuntu-20.04,ubuntu-22.04,macos-10.15,macos-11,macos-12] exclude: - os: ubuntu-18.04 python-version: 3.6 @@ -69,12 +110,6 @@ jobs: with: python-version: ${{ matrix.python-version }} -# - name: Install dependencies by cloning from GitHub MultiRunnable -# run: | -# git clone https://github.com/Chisanan232/multirunnable.git -b master ./multirunnable -# sudo python ./multirunnable/setup.py install -# pip install -r ./multirunnable/dev-requirements.txt - - name: Install Python dependencies run: | python -m pip install --upgrade pip @@ -82,6 +117,14 @@ jobs: pip install -U -r ./requirements/requirements.txt pip install -U -r ./requirements/requirements-test.txt + - name: Setup and run HTTP server for testing + if: ${{ inputs.setup_http_server == true }} + run: gunicorn --bind ${{ inputs.http_server_host }}:${{ inputs.http_server_port }} '${{ inputs.http_server_app_module }}:${{ inputs.http_server_enter_point }}' --daemon + + - name: Test to send HTTP request to sample HTTP server + if: ${{ inputs.setup_http_server == true }} + run: curl "http://${{ inputs.http_server_host }}:${{ inputs.http_server_port }}/exchangeReport/STOCK_DAY?response=json&date=20170101&stockNo=2331" + - name: Run tests with pytest run: pytest ${{ matrix.test-path }} continue-on-error: true @@ -96,3 +139,50 @@ jobs: path: .coverage.${{ inputs.test_type }}.${{ matrix.os }}-${{ matrix.python-version }} if-no-files-found: error + + run_test_items_with_debug_mode: + if: ${{ inputs.debug_mode == true }} + runs-on: ${{ matrix.os }} + + strategy: + matrix: + python-version: ['3.10'] + os: [ubuntu-22.04] + test-path: ${{fromJson(inputs.all_test_items_paths)}} + + steps: + - uses: actions/checkout@v2 + + - name: Install Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Install Python dependencies + run: | + python -m pip install --upgrade pip + pip install -U pip + pip install -U -r ./requirements/requirements.txt + pip install -U -r ./requirements/requirements-test.txt + + - name: Setup and run HTTP server for testing + if: ${{ inputs.setup_http_server == true }} + run: gunicorn --bind ${{ inputs.http_server_host }}:${{ inputs.http_server_port }} '${{ inputs.http_server_app_module }}:${{ inputs.http_server_enter_point }}' --daemon + + - name: Test to send HTTP request to sample HTTP server + if: ${{ inputs.setup_http_server == true }} + run: curl "http://${{ inputs.http_server_host }}:${{ inputs.http_server_port }}/exchangeReport/STOCK_DAY?response=json&date=20170101&stockNo=2331" + + - name: Run tests with pytest + run: pytest ${{ matrix.test-path }} + continue-on-error: true + + - name: Rename the code coverage result file + run: mv ./.coverage ./.coverage.${{ inputs.test_type }}.${{ matrix.os }}-${{ matrix.python-version }} + + - name: Upload code coverage result file + uses: actions/upload-artifact@v3 + with: + name: coverage + path: .coverage.${{ inputs.test_type }}.${{ matrix.os }}-${{ matrix.python-version }} + if-no-files-found: error diff --git a/.github/workflows/test_gh_reusable_workflow.yaml b/.github/workflows/test_gh_reusable_workflow.yaml new file mode 100644 index 00000000..af75f426 --- /dev/null +++ b/.github/workflows/test_gh_reusable_workflow.yaml @@ -0,0 +1,56 @@ +name: GitHub Action reusable workflow project CI Test + +on: + push: + branches: + - "develop" + - "release" + - "release-**" + - "release/**" + - "master" + paths-ignore: + - ".gitcommitrules" + - ".gitignore" + - "LICENSE" + - "README.md" + + pull_request: + branches: + - "develop" + - "release" + - "release-**" + - "release/**" + - "master" + paths-ignore: + - ".gitcommitrules" + - ".gitignore" + - "LICENSE" + - "README.md" + +jobs: + test_build_git-tag_and_create_github-release: +# name: Build git tag and GitHub release if it needs + uses: ./.github/workflows/build_git-tag_and_create_github-release.yaml + with: + project_type: github-action-reusable-workflow + debug_mode: true + + + test_deploy_as_new_branch: +# name: Create new git branch by the tagged commit + needs: test_build_git-tag_and_create_github-release + if: ${{ github.event_name == 'push' && + needs.test_build_git-tag_and_create_github-release.outputs.github-action_reusable_workflow_release_version != 'Initial' && + needs.test_build_git-tag_and_create_github-release.outputs.github-action_reusable_workflow_release_version != 'Pre' }} + runs-on: ubuntu-latest + env: + RELEASE_TYPE: ${{ needs.test_build_git-tag_and_create_github-release.outputs.github-action_reusable_workflow_release_version }} + steps: + - uses: actions/checkout@v2 + + - name: Check it whether get the output of previous one job which has version info or not + run: bash scripts/ci/check_getting_output.sh + + - name: Create new git branch by the tagged commit + run: bash ./scripts/ci/deployment_new_version_workflow.sh 'true' + diff --git a/.github/workflows/test-reusable-workflows.yaml b/.github/workflows/test_python_project_ci_multi-tests.yaml similarity index 52% rename from .github/workflows/test-reusable-workflows.yaml rename to .github/workflows/test_python_project_ci_multi-tests.yaml index 25f1a897..ec33747d 100644 --- a/.github/workflows/test-reusable-workflows.yaml +++ b/.github/workflows/test_python_project_ci_multi-tests.yaml @@ -1,4 +1,5 @@ -name: github-action reusable workflows test +name: Python project CI Test (multi-tests) + on: push: branches: @@ -12,12 +13,14 @@ on: - ".gitignore" - "LICENSE" - "README.md" + pull_request: branches: - "develop" - "release" - "release-**" - "release/**" + - "master" paths-ignore: - ".gitcommitrules" - ".gitignore" @@ -25,12 +28,11 @@ on: - "README.md" jobs: - prep-testbed_unit-test: # name: Prepare all unit test items uses: ./.github/workflows/prepare_test_items.yaml with: - shell_path: scripts/ci/get-unit-test-paths.sh + shell_path: scripts/ci/test/get-unit-test-paths.sh shell_arg: unix @@ -38,7 +40,7 @@ jobs: # name: Prepare all integration test items uses: ./.github/workflows/prepare_test_items.yaml with: - shell_path: scripts/ci/get-integration-test-paths.sh + shell_path: scripts/ci/test/get-integration-test-paths.sh shell_arg: unix @@ -49,6 +51,7 @@ jobs: with: test_type: unit-test all_test_items_paths: ${{needs.prep-testbed_unit-test.outputs.all_test_items}} + debug_mode: true run_integration-test: @@ -58,59 +61,71 @@ jobs: with: test_type: integration-test all_test_items_paths: ${{needs.prep-testbed_integration-test.outputs.all_test_items}} + setup_http_server: true + http_server_host: 0.0.0.0 + http_server_port: 30303 + http_server_app_module: test._http_server.app + http_server_enter_point: app + debug_mode: true unit-test_codecov: # name: Organize and generate the testing report and upload it to Codecov needs: run_unit-test - uses: ./.github/workflows/organize_all_testing_coverage_reports_with_different_os_and_py_version.yaml + uses: ./.github/workflows/organize_and_generate_test_cov_reports.yaml with: test_type: unit-test - generate_xml_report_finally: false integration-test_codecov: # name: Organize and generate the testing report and upload it to Codecov needs: run_integration-test - uses: ./.github/workflows/organize_all_testing_coverage_reports_with_different_os_and_py_version.yaml + uses: ./.github/workflows/organize_and_generate_test_cov_reports.yaml with: test_type: integration-test - generate_xml_report_finally: false - organize_all-test_codecov_and_generate_report: + codecov_finish: # name: Organize and generate the testing report and upload it to Codecov +# if: github.ref_name == 'release' || github.ref_name == 'master' needs: [unit-test_codecov, integration-test_codecov] - uses: ./.github/workflows/organize_all_testing_reports_with_different_test_type.yaml + uses: ./.github/workflows/upload_test_cov_report.yaml + secrets: + codecov_token: ${{ secrets.CODECOV_TOKEN }} + with: + test_type: all-test + upload-to-codecov: true + codecov_flags: unit,integration # Required if 'upload-to-codecov' is true + codecov_name: gh_workflow_template # Required if 'upload-to-codecov' is true - codecov_finish: -# name: Organize and generate the testing report and upload it to Codecov - if: github.ref_name == 'release' || github.ref_name == 'master' - needs: organize_all-test_codecov_and_generate_report - uses: ./.github/workflows/upload_test_report_to_codecov.yaml + coveralls_finish: +# name: Organize and generate the testing report and upload it to Coveralls +# if: github.ref_name == 'release' || github.ref_name == 'master' + needs: [unit-test_codecov, integration-test_codecov] + uses: ./.github/workflows/upload_test_cov_report.yaml secrets: - codecov_token: ${{ secrets.CODECOV_TOKEN }} + coveralls_token: ${{ secrets.COVERALLS_TOKEN }} with: - download_path: ./ - codecov_flags: unit,integration - codecov_name: smoothcrawler-appintegration_github-actions_test # optional + test_type: all-test + upload-to-coveralls: true codacy_finish: # name: Upload test report to Codacy to analyse and record code quality - needs: [codecov_finish] - uses: ./.github/workflows/upload_code_report_to_codacy.yaml + needs: [unit-test_codecov, integration-test_codecov] + uses: ./.github/workflows/upload_test_cov_report.yaml secrets: codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }} with: - download_path: ./ + test_type: all-test + upload-to-codacy: true # pre-building_check: ## name: Check about it could work finely by installing the Python package with setup.py file # needs: [codecov_finish, codacy_finish] -# uses: Chisanan232/GitHub-Action-Template-Python/.github/workflows/upload_code_report_to_codacy.yaml +# uses: ./.github/workflows/pre-building_test_setup_package.yaml # with: # python_package_name: smoothcrawler # test_import_package_code_1: import smoothcrawler as mr @@ -118,3 +133,33 @@ jobs: # test_import_package_code_3: from smoothcrawler.components.data import BaseHTTPResponseParser, BaseDataHandler # test_python_script: ./scripts/test_crawler.py + + build_git-tag_and_create_github-release: +# name: Build git tag and GitHub release if it needs + needs: [coveralls_finish, codacy_finish] + uses: ./.github/workflows/build_git-tag_and_create_github-release.yaml + with: + project_type: python-package + project_name: test_gh_workflow + software_version_format: general-3 + debug_mode: true + + + fake_build_pkg_and_push_to_pypi: +# name: Check about it could work finely by installing the Python package with setup.py file + needs: build_git-tag_and_create_github-release + if: github.event_name == 'push' + runs-on: ubuntu-latest + env: + RELEASE_TYPE: ${{ needs.build_git-tag_and_create_github-release.outputs.python_release_version }} + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Check it whether get the output of previous one job which has version info or not + run: bash scripts/ci/check_getting_output.sh + + - name: For testing about getting the software version info + run: | + echo "Release version: $RELEASE_TYPE" + diff --git a/.github/workflows/test_python_project_ci_one-test.yaml b/.github/workflows/test_python_project_ci_one-test.yaml new file mode 100644 index 00000000..f02d62a2 --- /dev/null +++ b/.github/workflows/test_python_project_ci_one-test.yaml @@ -0,0 +1,160 @@ +name: Python project CI Test (one-test) + +on: + push: + branches: + - "develop" + - "release" + - "release-**" + - "release/**" + - "master" + paths-ignore: + - ".gitcommitrules" + - ".gitignore" + - "LICENSE" + - "README.md" + pull_request: + branches: + - "develop" + - "release" + - "release-**" + - "release/**" + - "master" + paths-ignore: + - ".gitcommitrules" + - ".gitignore" + - "LICENSE" + - "README.md" + +jobs: + prep-testbed_unit-test: +# name: Prepare all unit test items + uses: ./.github/workflows/prepare_test_items.yaml + with: + shell_path: scripts/ci/test/get-unit-test-paths.sh + shell_arg: unix + + + run_unit-test: +# name: Run all unit test items + needs: prep-testbed_unit-test + uses: ./.github/workflows/run_test_items_via_pytest.yaml + with: + test_type: unit-test + all_test_items_paths: ${{needs.prep-testbed_unit-test.outputs.all_test_items}} + debug_mode: true + + + unit-test_codecov: +# name: Organize and generate the testing report and upload it to Codecov + needs: run_unit-test + uses: ./.github/workflows/organize_and_generate_test_cov_reports.yaml + with: + test_type: unit-test + + +# codecov_finish: +## name: Organize and generate the testing report and upload it to Codecov +## if: github.ref_name == 'release' || github.ref_name == 'master' +# needs: [unit-test_codecov] +# uses: ./.github/workflows/upload_test_cov_report.yaml +# secrets: +# codecov_token: ${{ secrets.CODECOV_TOKEN }} +# with: +# test_type: unit-test +# upload-to-codecov: true +# codecov_flags: unit # Required if 'upload-to-codecov' is true +# codecov_name: gh_workflow_template # Required if 'upload-to-codecov' is true + + + coveralls_finish: +# name: Organize and generate the testing report and upload it to Coveralls +# if: github.ref_name == 'release' || github.ref_name == 'master' + needs: [unit-test_codecov] + uses: ./.github/workflows/upload_test_cov_report.yaml + secrets: + coveralls_token: ${{ secrets.COVERALLS_TOKEN }} + with: + test_type: unit-test + upload-to-coveralls: true + + + codacy_finish: +# name: Upload test report to Codacy to analyse and record code quality + needs: [unit-test_codecov] + uses: ./.github/workflows/upload_test_cov_report.yaml + secrets: + codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }} + with: + test_type: unit-test + upload-to-codacy: true + + +# pre-building_check: +## name: Check about it could work finely by installing the Python package with setup.py file +# if: github.event_name == 'push' && (github.ref_name == 'release' || github.ref_name == 'master') +# needs: [codecov_finish, codacy_finish] +# uses: ./.github/workflows/pre-building_test_setup_package.yaml +# with: +# python_package_name: smoothcrawler +# test_import_package_code_1: import smoothcrawler as mr +# test_import_package_code_2: from smoothcrawler.crawler import SimpleCrawler +# test_import_package_code_3: from smoothcrawler.components.data import BaseHTTPResponseParser, BaseDataHandler +# test_python_script: ./scripts/test_crawler.py + + + build_git-tag_and_create_github-release: +# name: Build git tag and GitHub release if it needs + needs: [coveralls_finish, codacy_finish] + uses: ./.github/workflows/build_git-tag_and_create_github-release.yaml + with: + project_type: python-package + project_name: test_gh_workflow + software_version_format: general-3 + debug_mode: true + + + fake_build_pkg_and_push_to_pypi: +# name: Check about it could work finely by installing the Python package with setup.py file + needs: build_git-tag_and_create_github-release + if: github.event_name == 'push' + runs-on: ubuntu-latest + env: + RELEASE_TYPE: ${{ needs.build_git-tag_and_create_github-release.outputs.python_release_version }} + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Check it whether get the output of previous one job which has version info or not + run: bash scripts/ci/check_getting_output.sh +# run: | +# release_version=$(echo $RELEASE_TYPE) +# if [ "$release_version" != "" ]; then +# echo "๐Ÿ“ฌ๐ŸŽ‰๐Ÿป It gets data which is release version info!" +# exit 0 +# else +# echo "๐Ÿ“ญ๐Ÿ™ˆ It doesn't get any data which is release version info." +# exit 1 +# fi + + - name: For testing about getting the software version info + run: | + echo "Release version: $RELEASE_TYPE" + + +# compile_and_build_python_pkg: +## name: Compile the Python source code and build it as Python package files +# if: github.event_name == 'push' && github.ref_name == 'master' +# needs: pre-building_check +# uses: ./.github/workflows/build_package.yaml + + +# push_python_pkg_to_pypi: +## name: Upload the Python package files which has been compiled to PyPi +# if: github.event_name == 'push' && github.ref_name == 'master' +# needs: compile_and_build_python_pkg +# uses: ./.github/workflows/push_pkg_to_pypi.yaml +# secrets: +# pypi_user: ${{ secrets.PYPI_USERNAME }} +# pypi_token: ${{ secrets.PYPI_PASSWORD }} + diff --git a/.github/workflows/upload_code_report_to_codacy.yaml b/.github/workflows/upload_code_report_to_codacy.yaml deleted file mode 100644 index 709003e7..00000000 --- a/.github/workflows/upload_code_report_to_codacy.yaml +++ /dev/null @@ -1,52 +0,0 @@ -############################################################################ -# -# Workflow Description: -# Upload the testing coverage reports to Codacy. -# -# Workflow input parameters: -# * General arguments: -# * download_path: The path to download testing coverage reports via 'actions/download-artifact@v3'. -# -# * Secret arguments: -# * codacy_token: The API token for uploading testing coverage report to Codacy. -# -# Workflow running output: -# No and do nothing. -# -############################################################################ - -name: Upload code detail report to Codacy - -on: - workflow_call: - inputs: - download_path: - description: "The path to download testing coverage reports via 'actions/download-artifact@v3'." - required: true - type: string - - secrets: - codacy_token: - description: "The API token for uploading testing coverage report to Codacy." - required: true - - -jobs: - upload_code_to_codacy_check_quality: - runs-on: ubuntu-latest - steps: - - name: Download testing coverage report - uses: actions/download-artifact@v3 - with: - name: final_project_testing_coverage_report - path: ${{ inputs.download_path }} - - - name: Generate testing report for Codacy - run: mv ./coverage.xml ./cobertura.xml - - - name: Upload testing report to Codacy - uses: codacy/codacy-coverage-reporter-action@v1 - with: - project-token: ${{ secrets.codacy_token }} - coverage-reports: cobertura.xml - diff --git a/.github/workflows/upload_test_cov_report.yaml b/.github/workflows/upload_test_cov_report.yaml new file mode 100644 index 00000000..b83755d3 --- /dev/null +++ b/.github/workflows/upload_test_cov_report.yaml @@ -0,0 +1,180 @@ +################################################################################################################################### +# +# Workflow Description: +# Upload the testing coverage reports to Codecov. +# +# Workflow input parameters: +# * General arguments: +# * download_path: The path to download testing coverage reports via 'actions/download-artifact@v3'. +# * test_type: The testing type. In generally, it only has 2 options: 'unit-test' and 'integration-test'. +# * upload-to-codecov: If it's true, it would upload testing coverage report for Codecov (https://codecov.io). +# * codecov_flags: The flags of the testing coverage report for Codecov. This option would be required if 'upload-to-codecov' is true. +# * codecov_name: The name of the testing coverage report for Codecov. This option would be required if 'upload-to-codecov' is true. +# * upload-to-coveralls: If it's true, it would upload testing coverage report for Coveralls (https://coveralls.io). +# * upload-to-codacy: If it's true, it would upload testing coverage report for Codacy (https://app.codacy.com/). +# +# * Secret arguments: +# * codecov_token: The API token for uploading testing coverage report to Codecov. +# * coveralls_token: The API token for uploading testing coverage report to Coveralls. +# * codacy_token: The API token for uploading testing coverage report to Codacy. +# +# Workflow running output: +# No and do nothing. +# +################################################################################################################################### + +name: Upload test report to Codecov + +on: + workflow_call: + inputs: + download_path: + description: "The path to download testing coverage reports via 'actions/download-artifact@v3'." + type: string + required: false + default: ./ + test_type: + description: "The testing type. In generally, it only has 2 options: 'unit-test' and 'integration-test'." + required: true + type: string + upload-to-codecov: + description: "If it's true, it would upload testing coverage report for Codecov (https://codecov.io)." + type: boolean + required: false + default: false + codecov_flags: + description: "The flags of the testing coverage report for Codecov. This option would be required if 'upload-to-codecov' is true." + type: string + required: false + default: '' + codecov_name: + description: "The name of the testing coverage report for Codecov. This option would be required if 'upload-to-codecov' is true." + type: string + required: false + default: '' + upload-to-coveralls: + description: "If it's true, it would upload testing coverage report for Coveralls (https://coveralls.io)." + type: boolean + required: false + default: false + upload-to-codacy: + description: "If it's true, it would upload testing coverage report for Codacy (https://app.codacy.com/)." + type: boolean + required: false + default: false + + secrets: + codecov_token: + description: "The API token for uploading testing coverage report to Codecov." + required: false + coveralls_token: + description: "The API token for uploading testing coverage report to Coveralls." + required: false + codacy_token: + description: "The API token for uploading testing coverage report to Codacy." + required: false + + +jobs: + upload_test_cov_report: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Download shell script for checking input parameters + run: curl https://raw.githubusercontent.com/Chisanan232/GitHub-Action_Workflow-Template-Python/develop/scripts/ci/check-input-params.sh --output ./scripts/ci/check-input-params.sh + + - name: Check the workflow input parameter + run: | + echo "Check the parameters of uploading report to Codecov ..." + bash ./scripts/ci/check-input-params.sh ${{ inputs.upload-to-codecov }} ${{ secrets.codecov_token }} + + echo "Check the parameters of uploading report to Coveralls ..." + bash ./scripts/ci/check-input-params.sh ${{ inputs.upload-to-coveralls }} ${{ secrets.coveralls_token }} + + echo "Check the parameters of uploading report to Codacy ..." + bash ./scripts/ci/check-input-params.sh ${{ inputs.upload-to-codacy }} ${{ secrets.codacy_token }} + + - name: Download code coverage result files which has be handled by different test type process + uses: actions/download-artifact@v3 + with: + name: test_coverage_report + path: ${{ inputs.download_path }} + + - name: Download code coverage result files which has be handled by different test type process + uses: actions/download-artifact@v3 + with: + name: test_coverage_xml_report + path: ${{ inputs.download_path }} + + - name: Install Python 3.10 + if: ${{ inputs.upload-to-codecov == true || inputs.upload-to-coveralls == true }} + uses: actions/setup-python@v2 + with: + python-version: "3.10" + + - name: Install Python dependencies about handling testing coverage report + if: ${{ inputs.upload-to-codecov == true || inputs.upload-to-coveralls == true }} + run: | + python3 -m pip install --upgrade pip + pip3 install -U pip + + - name: Install Python dependencies about tool of Codecov + if: ${{ inputs.upload-to-codecov == true }} + run: pip3 install codecov + + - name: Upload coverage report to Codecov https://codecov.io (For Unit-Test or Integration-Test) + if: ${{ inputs.upload-to-codecov == true && (inputs.test_type == 'unit-test' || inputs.test_type == 'integration-test') }} + run: | + codecov \ + -t ${{ secrets.codecov_token }} \ + --file coverage_${{ inputs.test_type }}.xml \ + --flags ${{ inputs.codecov_flags }} \ + --env OS,PYTHON \ + --name ${{ inputs.codecov_name }} \ + --verbose + + - name: Upload coverage report to Codecov https://codecov.io (For all test types) + if: ${{ inputs.upload-to-codecov == true && inputs.test_type == 'all-test' }} + run: | + codecov \ + -t ${{ secrets.codecov_token }} \ + --file coverage_unit-test.xml \ + --file coverage_integration-test.xml \ + --flags ${{ inputs.codecov_flags }} \ + --env OS,PYTHON \ + --name ${{ inputs.codecov_name }} \ + --verbose + + - name: Install Python dependencies about tool of Coveralls + if: ${{ inputs.upload-to-coveralls == true }} + run: | + pip3 install coveralls + pip3 install coverage + + - name: Combine all testing code coverage result files with all test types + if: ${{ inputs.upload-to-coveralls == true }} + run: coverage combine .coverage.* + + - name: Upload coverage report to Coveralls https://coveralls.io + if: ${{ inputs.upload-to-coveralls == true }} + env: + GITHUB_TOKEN: ${{ secrets.coveralls_token }} + run: coveralls --verbose + + - name: Upload testing report to Codacy https://app.codacy.com/ (For Unit-Test or Integration-Test) + if: ${{ inputs.upload-to-codacy == true && (inputs.test_type == 'unit-test' || inputs.test_type == 'integration-test') }} + uses: codacy/codacy-coverage-reporter-action@v1 + with: + project-token: ${{ secrets.codacy_token }} + coverage-reports: coverage_${{ inputs.test_type }}.xml +# coverage-reports: cobertura.xml + + - name: Upload testing report to Codacy https://app.codacy.com/ (For all test types) + if: ${{ inputs.upload-to-codacy == true && inputs.test_type == 'all-test' }} + uses: codacy/codacy-coverage-reporter-action@v1 + with: + project-token: ${{ secrets.codacy_token }} + coverage-reports: coverage_unit-test.xml,coverage_integration-test.xml +# coverage-reports: cobertura.xml diff --git a/.github/workflows/upload_test_report_to_codecov.yaml b/.github/workflows/upload_test_report_to_codecov.yaml deleted file mode 100644 index 6912f550..00000000 --- a/.github/workflows/upload_test_report_to_codecov.yaml +++ /dev/null @@ -1,72 +0,0 @@ -############################################################################ -# -# Workflow Description: -# Upload the testing coverage reports to Codecov. -# -# Workflow input parameters: -# * General arguments: -# * download_path: The path to download testing coverage reports via 'actions/download-artifact@v3'. -# * codecov_flags: The flags of the testing coverage report for Codecov. -# * codecov_name: The name of the testing coverage report for Codecov. -# -# * Secret arguments: -# * codecov_token: The API token for uploading testing coverage report to Codecov. -# -# Workflow running output: -# No and do nothing. -# -############################################################################ - -name: Upload test report to Codecov - -on: - workflow_call: - inputs: - download_path: - description: "The path to download testing coverage reports via 'actions/download-artifact@v3'." - required: true - type: string - codecov_flags: - description: "The flags of the testing coverage report for Codecov." - required: true - type: string - codecov_name: - description: "The name of the testing coverage report for Codecov." - required: true - type: string - - secrets: - codecov_token: - description: "The API token for uploading testing coverage report to Codecov." - required: true - - -jobs: - upload_report_to_codecov: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Download code coverage result file - uses: actions/download-artifact@v3 - with: - name: final_project_testing_coverage_report - path: ${{ inputs.download_path }} - - - name: Upload coverage report to platform Codecov - uses: codecov/codecov-action@v3 - with: - token: ${{ secrets.codecov_token }} # not required for public repos - files: coverage.xml # optional - flags: ${{ inputs.codecov_flags }} # optional - name: ${{ inputs.codecov_name }} # optional - fail_ci_if_error: true # optional (default = false) - verbose: true # optional (default = false) - - - name: Upload testing coverage report - uses: actions/upload-artifact@v3 - with: - name: project_coverage_report - path: coverage.xml - if-no-files-found: error diff --git a/README.md b/README.md index ce3332c4..2df6bf5f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ # GitHub Action - Workflow template for Python library -[![github-action reusable workflows test](https://github.com/Chisanan232/GitHub-Action-Template-Python/actions/workflows/test-reusable-workflows.yaml/badge.svg)](https://github.com/Chisanan232/GitHub-Action-Template-Python/actions/workflows/test-reusable-workflows.yaml) +[![Release](https://img.shields.io/github/release/Chisanan232/GitHub-Action-Template-Python.svg?label=Release&logo=github)](https://github.com/Chisanan232/GitHub-Action-Template-Python/releases) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg?logo=apache)](https://opensource.org/licenses/Apache-2.0) +[![Python project CI Test (one-test)](https://github.com/Chisanan232/GitHub-Action_Workflow-Template-Python/actions/workflows/test_python_project_ci_one-test.yaml/badge.svg)](https://github.com/Chisanan232/GitHub-Action_Workflow-Template-Python/actions/workflows/test_python_project_ci_one-test.yaml) +[![Python project CI Test (multi-tests)](https://github.com/Chisanan232/GitHub-Action_Workflow-Template-Python/actions/workflows/test_python_project_ci_multi-tests.yaml/badge.svg)](https://github.com/Chisanan232/GitHub-Action_Workflow-Template-Python/actions/workflows/test_python_project_ci_multi-tests.yaml) +[![GitHub Action reusable workflow project CI Test](https://github.com/Chisanan232/GitHub-Action_Workflow-Template-Python/actions/workflows/test_gh_reusable_workflow.yaml/badge.svg)](https://github.com/Chisanan232/GitHub-Action_Workflow-Template-Python/actions/workflows/test_gh_reusable_workflow.yaml) This is a GitHub Action workflow template for **_Python library_** project. @@ -25,21 +28,22 @@ The usage of each workflow template. * [_prepare_test_items.yaml_](#prepare_test_itemsyaml) * [_run_test_items_via_pytest.yaml_](#run_test_items_via_pytestyaml) -* [_organize_all_testing_coverage_reports_with_different_os_and_py_version.yaml_](#organize_all_testing_coverage_reports_with_different_os_and_py_versionyaml) -* [_organize_all_testing_reports_with_different_test_type.yaml_](#organize_all_testing_reports_with_different_test_typeyaml) -* [_upload_test_report_to_codecov.yaml_](#upload_test_report_to_codecovyaml) -* [_upload_code_report_to_codacy.yaml_](#upload_code_report_to_codacyyaml) +* [_organize_and_generate_test_cov_reports.yaml_](#organize_and_generate_test_cov_reportsyaml) +* [_upload_test_cov_report.yaml_](#upload_test_cov_reportyaml) +* [_build_git-tag_and_create_github-release.yaml_](#build_git-tag_and_create_github-releaseyaml) + +
-#### _prepare_test_items.yaml_ +### _prepare_test_items.yaml_ * Description: Prepare the test items. * Options: -| option name | function content | -|-------------|------------------------------------------------------| -| shell_path | The path shell script for getting the testing items. | -| shell_arg | Input arguments of the shell script. | +| option name | data type | optional or required | function content | +|-------------|-----------|----------------------|------------------------------------------------------| +| shell_path | string | Required | The path shell script for getting the testing items. | +| shell_arg | string | Required | Input arguments of the shell script. | * Output: * all_test_items: All the test items it would run. @@ -61,20 +65,30 @@ And we could get this workflow output result via keyword _all_test_items_.
-#### _run_test_items_via_pytest.yaml_ +### _run_test_items_via_pytest.yaml_ * Description: Run testing by specific type with all test items via PyTest and generate its testing coverage report (it would save reports by _actions/upload-artifact@v3_). * Options: -| option name | function content | -|----------------------|--------------------------------------------------------------------------------------------| -| test_type | The testing type. In generally, it only has 2 options: _unit-test_ and _integration-test_. | -| all_test_items_paths | The target paths of test items under test. | +| option name | data type | optional or required | function content | +|-------------------------|-----------|--------------------------------------|--------------------------------------------------------------------------------------------| +| test_type | string | Required | The testing type. In generally, it only has 2 options: _unit-test_ and _integration-test_. | +| all_test_items_paths | string | Required | The target paths of test items under test. | +| setup_http_server | string | Optional, Default value is _false_ | If it's true, it would set up and run HTTP server for testing. | +| http_server_host | string | Optional, Default value is _0.0.0.0_ | The host IPv4 address of HTTP server. | +| http_server_port | string | Optional, Default value is _12345_ | The port number of HTTP server. | +| http_server_app_module | string | Optional, Default value is _app_ | The module path of HTTP server. | +| http_server_enter_point | string | Optional, Default value is _app_ | The object about the web application. | +| debug_mode | boolean | Optional, Default value is _false_ | For debug, so it's matrix would only has one os: ubuntu-22.04 & one python-version: 3.10. | * Output: No, but it would save the testing coverage reports to provide after-process to organize and record. +| Upload-Artifact name | description | +|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| coverage | The test coverage report which be generated by PyTest, and it's recorded after run test done. The file name format would be .coverage..- | + * How to use it? ```yaml @@ -85,6 +99,11 @@ No, but it would save the testing coverage reports to provide after-process to o with: test_type: unit-test all_test_items_paths: ${{needs.prepare-testing-items_unit-test.outputs.all_test_items}} + setup_http_server: true + http_server_host: 0.0.0.0 + http_server_port: 30303 + http_server_app_module: test._http_server.app + http_server_enter_point: app ``` Please take a look of option _all_test_items_paths_. You could find that it get the input result of @@ -99,19 +118,23 @@ is provided by previous workflow? That is all testing items.
-#### _organize_all_testing_coverage_reports_with_different_os_and_py_version.yaml_ +### _organize_and_generate_test_cov_reports.yaml_ -* Description: Organize all the testing coverage reports. (it would save reports by _actions/upload-artifact@v3_). +* Description: Organize all the testing coverage reports which be generated in different runtime OS with Python version. (it would save reports by _actions/upload-artifact@v3_). * Options: -| option name | function content | -|-----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| test_type | The testing type. In generally, it only has 2 options: _unit-test_ and _integration-test_. | -| generate_xml_report_finally | Something, it only has 1 test type currently. So it could let this option to be 'true' than it would generate XML report finally to let uploading process to use it directly. | +| option name | data type | optional or required | function content | +|-------------|-----------|----------------------|--------------------------------------------------------------------------------------------| +| test_type | string | Required | The testing type. In generally, it only has 2 options: _unit-test_ and _integration-test_. | * Output: -No, but it would save the testing coverage reports (coverage.xml) to provide after-process to organize and record. +No, but it would save the testing coverage reports to provide after-process to organize and record. + +| Upload-Artifact name | description | +|--------------------------|-----------------------------------------------------------------------------------------------------------------| +| test_coverage_report | The handled test coverage report (.coverage file). It's file name format would be .coverage.. | +| test_coverage_xml_report | The handled test coverage report (.xml file). It's file name format would be coverage_.xml. | * How to use it? @@ -119,60 +142,16 @@ No, but it would save the testing coverage reports (coverage.xml) to provide aft unit-test_codecov: # name: Organize and generate the testing report and upload it to Codecov needs: run_unit-test - uses: Chisanan232/GitHub-Action-Template-Python/.github/workflows/organize_all_testing_coverage_reports_with_different_os_and_py_version.yaml@master + uses: Chisanan232/GitHub-Action-Template-Python/.github/workflows/organize_and_generate_test_cov_reports.yaml@master with: test_type: unit-test - generate_xml_report_finally: true ``` It would upload the organized report via _actions/upload-artifact@v3_. And it doesn't support customize options of _actions/upload-artifact@v3_ currently.
-#### _organize_all_testing_reports_with_different_test_type.yaml_ - -* Description: Organize all the testing coverage reports. (it would save reports by _actions/upload-artifact@v3_). -* Options: - -It has no input parameter. - -* Output: - -No, but it would save the testing coverage reports (coverage.xml) to provide after-process to organize and record. - -* How to use it? - -```yaml - organize_all-test_codecov_and_generate_report: -# name: Organize and generate the testing report and upload it to Codecov - needs: [unit-test_codecov, integration-test_codecov] - uses: Chisanan232/GitHub-Action-Template-Python/.github/workflows/organize_all_testing_reports_with_different_test_type.yaml@master -``` - -This workflow is very close with another workflow _organize_all_testing_coverage_reports_with_different_os_and_py_version.yaml_. -But they're different. In a software test, it may have one or more test types it would run to check the software quality. -So let us consider below 2 scenarios: - -First scenario, it has only one test. So the CI workflow would be like below: - - get test items -> run test -> organize and generate testing report - -Second one, it has 2 tests: _Unit test_ and _Integration test_: - - get unit test items -> run unit test -> organize unit test report ------------------------ - |-> organize and generate final test report - get integration test items -> run integration test -> organize integration test report --- - -So it should organize testing coverage reports twice, first time is organizing report with one specific test type, -another one time is organizing these 2 test types reports. -Hence, the different is: -* _organize_all_testing_coverage_reports_with_different_os_and_py_version.yaml_ is the first process to organize testing coverage reports. - And it could set option _generate_xml_report_finally_ as _true_ to let the CI workflow be more clear and simpler if it has only one test type. -* _organize_all_testing_reports_with_different_test_type.yaml_ is the second organizing process if it has 2 more test types in CI workflow. - -
- -#### _upload_test_report_to_codecov.yaml_ +### _upload_test_cov_report.yaml_ * Description: Upload the testing coverage reports to Codecov. * Options: @@ -181,17 +160,23 @@ It has 2 different types option could use: _General option_: -| option name | function content | -|---------------|-----------------------------------------------------------------------------------| -| download_path | The path to download testing coverage reports via _actions/download-artifact@v3_. | -| codecov_flags | The flags of the testing coverage report for Codecov. | -| codecov_name | The name of the testing coverage report for Codecov. | +| option name | data type | optional or required | function content | +|---------------------|-----------|------------------------------------------|---------------------------------------------------------------------------------------------------------------------| +| download_path | string | Optional. Default value is './'. | The path to download testing coverage reports via _actions/download-artifact@v3_. | +| test_type | string | Required | The testing type. In generally, it only has 3 options: _unit-test_, _integration-test_ and _all-type_. | +| upload-to-codecov | boolean | Optional. Default value is _false_. | If it's true, it would upload testing coverage report for Codecov (https://codecov.io). | +| codecov_flags | string | Optional. Default value is empty string. | The flags of the testing coverage report for Codecov. This option would be required if _upload-to-codecov_ is true. | +| codecov_name | string | Optional. Default value is empty string. | The name of the testing coverage report for Codecov. This option would be required if _upload-to-codecov_ is true. | +| upload-to-coveralls | boolean | Optional. Default value is _false_. | If it's true, it would upload testing coverage report for Coveralls (https://coveralls.io). | +| upload-to-codacy | boolean | Optional. Default value is _false_. | If it's true, it would upload testing coverage report for Codacy (https://app.codacy.com/). | _Secret option_: -| option name | function content | -|---------------|-----------------------------------------------------------------| -| codecov_token | The API token for uploading testing coverage report to Codecov. | +| option name | option is optional or required | function content | +|-----------------|------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------| +| codecov_token | Optional. Default value is empty string. | The API token for uploading testing coverage report to Codecov. This option would be required if _upload-to-codecov_ is true. | +| coveralls_token | Optional. Default value is empty string. | The API token for uploading testing coverage report to Coveralls. This option would be required if _upload-to-coveralls_ is true. | +| codacy_token | Optional. Default value is empty string. | The API token for uploading testing coverage report to Codacy. This option would be required if _upload-to-codacy_ is true. | * Output: @@ -199,68 +184,127 @@ Nothing. * How to use it? -Before run this workflow, please make sure testing coverage report is ready. - -```yaml - codecov_finish: -# name: Organize and generate the testing report and upload it to Codecov - needs: [unit-test_codecov] - uses: Chisanan232/GitHub-Action-Template-Python/.github/workflows/upload_test_report_to_codecov.yaml@master - secrets: - codecov_token: ${{ secrets.CODECOV_TOKEN }} - with: - download_path: ./ - codecov_flags: unittests - codecov_name: smoothcrawler-cluster_github-actions_test # optional -``` - -* The badges would be generated after this workflow done: - -[![codecov](https://codecov.io/gh/Chisanan232/GitHub-Action-Template-Python/branch/master/graph/badge.svg?token=wbPgJ4wxOl)](https://codecov.io/gh/Chisanan232/GitHub-Action-Template-Python) + โš ๏ธ Before run this reusable workflow, please make sure testing coverage report is ready.
+ + โ”What format of test coverage report it could use? Different platform would need different format. But basically, it only accepts 2 types: _.coverage_ & _.xml_. + + ๐Ÿ‘€ This reusable work flow would check the input parameters first. The specific platform token shouldn't be empty where uploading flag is true. + + * Uploading test coverage report to **_Codecov_** (accepted report format: _.xml_) + + In Codecov case, it would need other 2 necessary options _codecov_flags_ & _codecov_name_. + + ```yaml + codecov_finish: + # name: Organize and generate the testing report and upload it to Codecov + needs: [unit-test_codecov] + uses: Chisanan232/GitHub-Action-Template-Python/.github/workflows/upload_test_cov_report.yaml@master + secrets: + codecov_token: ${{ secrets.CODECOV_TOKEN }} + with: + test_type: unit-test + upload-to-codecov: true + codecov_flags: unittests # required if upload-to-codecov is true + codecov_name: smoothcrawler-cluster_github-actions_test # required if upload-to-codecov is true + ``` + + The badge it generates: + + [![codecov](https://codecov.io/gh/Chisanan232/GitHub-Action-Template-Python/branch/master/graph/badge.svg?token=wbPgJ4wxOl)](https://codecov.io/gh/Chisanan232/GitHub-Action-Template-Python) + + * Uploading test coverage report to **_Coveralls_** (accepted report format: _.coverage_) + + In Coveralls case, the Python tool _coveralls_ only accept _.coverage_ type report so that it would do coverage process again (integrate all test types report into one report). + + ```yaml + codecov_finish: + # name: Organize and generate the testing report and upload it to Coveralls + needs: [unit-test_codecov] + uses: Chisanan232/GitHub-Action-Template-Python/.github/workflows/upload_test_cov_report.yaml@master + secrets: + coveralls_token: ${{ secrets.COVERALLS_TOKEN }} + with: + test_type: unit-test + upload-to-coveralls: true + ``` + + The badge it generates: + + [![Coverage Status](https://coveralls.io/repos/github/Chisanan232/GitHub-Action-Template-Python/badge.svg?branch=master)](https://coveralls.io/github/Chisanan232/GitHub-Action-Template-Python?branch=master) + + * Uploading test coverage report to **_Codacy_** (accepted report format: _.xml_) + + In Codacy case, please use **CODACY_PROJECT_TOKEN**, not **CODACY_API_TOKEN**. + + ```yaml + codecov_finish: + # name: Organize and generate the testing report and upload it to Codacy + needs: [unit-test_codecov] + uses: Chisanan232/GitHub-Action-Template-Python/.github/workflows/upload_test_cov_report.yaml@master + secrets: + codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }} + with: + test_type: unit-test + upload-to-codacy: true + ``` + + The badge it generates: + + [![Codacy Badge](https://app.codacy.com/project/badge/Grade/e8bfcd5830ba4232b45aca7c2d3e6310)](https://www.codacy.com/gh/Chisanan232/GitHub-Action-Template-Python/dashboard?utm_source=github.com&utm_medium=referral&utm_content=Chisanan232/GitHub-Action-Template-Python&utm_campaign=Badge_Grade) + [![Codacy Badge](https://app.codacy.com/project/badge/Coverage/e8bfcd5830ba4232b45aca7c2d3e6310)](https://www.codacy.com/gh/Chisanan232/GitHub-Action-Template-Python/dashboard?utm_source=github.com&utm_medium=referral&utm_content=Chisanan232/GitHub-Action-Template-Python&utm_campaign=Badge_Coverage)
-#### _upload_code_report_to_codacy.yaml_ +### _build_git-tag_and_create_github-release.yaml_ -* Description: Upload the testing coverage reports to Codacy. +* Description: Build a git tag on a specific commit in every git branch. And create GitHub release if current git branch is 'master'. * Options: -It has 2 different types option could use: +| option name | data type | optional or required | function content | +|-------------------------|-----------|-------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| project_type | string | Required | Different project type would get the software version info in different way. Currently, it only has 2 options: _python-package_ or _github-action-reusable-workflow_ | +| debug_mode | boolean | Optional, Default value is _false_ | It would run the tasks as log message, doesn't essentially run feature if this option is true. | +| project_name | string | Optional, Default value is _empty string_ | The project name. | +| software_version_format | string | Optional, Default value is _empty string_ | The format of software version. | -_General option_: +* Output: -| option name | function content | -|---------------|-----------------------------------------------------------------------------------| -| download_path | The path to download testing coverage reports via _actions/download-artifact@v3_. | +Yes, it has running result output. It would output the version which could provide after-process to verify what thing it should do, e.g., release or not. -_Secret option_: +| Workflow output | description | +|-------------------------------------------------|------------------------------------------------------------------------------------------------------| +| python_release_version | Python project release version info. It only has 2 types value: _Official-Release_ or _Pre-Release_. | +| github-action_reusable_workflow_release_version | Python project release version info. | -| option name | function content | -|--------------|----------------------------------------------------------------| -| codacy_token | The API token for uploading testing coverage report to Codacy. | +* How to use it? -* Output: + * **_Python package_** usage case: -Nothing. + ```yaml + build_git-tag_and_create_github-release: + # name: Build git tag and GitHub release if it needs for Python package project + needs: [coveralls_finish, codacy_finish] + uses: ./.github/workflows/build_git-tag_and_create_github-release.yaml + with: + project_type: python-package + project_name: test_gh_workflow + software_version_format: general-3 + debug_mode: true + ``` -* How to use it? + * **_GitHub Action reusable workflow_** usage case: -Before run this workflow, please make sure testing coverage report is ready. + ```yaml + build_git-tag_and_create_github-release: + # name: Build git tag and GitHub release if it needs for GitHub Action reusable workflow project + needs: [coveralls_finish, codacy_finish] + uses: ./.github/workflows/build_git-tag_and_create_github-release.yaml + with: + project_type: github-action-reusable-workflow + debug_mode: true + ``` -```yaml - codacy_finish: -# name: Upload test report to Codacy to analyse and record code quality - needs: [unit-test_codecov] - uses: Chisanan232/GitHub-Action-Template-Python/.github/workflows/upload_code_report_to_codacy.yaml@master - secrets: - codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }} - with: - download_path: ./ -``` +The badge it generates: -* The badges would be generated after this workflow done: +[![Release](https://img.shields.io/github/release/Chisanan232/GitHub-Action-Template-Python.svg?label=Release&logo=github)](https://github.com/Chisanan232/GitHub-Action-Template-Python/releases) -[![Codacy Badge](https://app.codacy.com/project/badge/Grade/e8bfcd5830ba4232b45aca7c2d3e6310)](https://www.codacy.com/gh/Chisanan232/GitHub-Action-Template-Python/dashboard?utm_source=github.com&utm_medium=referral&utm_content=Chisanan232/GitHub-Action-Template-Python&utm_campaign=Badge_Grade) -[![Codacy Badge](https://app.codacy.com/project/badge/Coverage/e8bfcd5830ba4232b45aca7c2d3e6310)](https://www.codacy.com/gh/Chisanan232/GitHub-Action-Template-Python/dashboard?utm_source=github.com&utm_medium=referral&utm_content=Chisanan232/GitHub-Action-Template-Python&utm_campaign=Badge_Coverage) - -
diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index b305b67a..00000000 --- a/codecov.yml +++ /dev/null @@ -1,4 +0,0 @@ -# # This test directory for testing to simulate a Python library project structure. - -codecov: - token: $CODECOV_TOKEN diff --git a/requirements/requirements-test.txt b/requirements/requirements-test.txt index a059ff3f..4cb4d2aa 100644 --- a/requirements/requirements-test.txt +++ b/requirements/requirements-test.txt @@ -9,3 +9,7 @@ pytest-rerunfailures >= 10.2 coverage >= 6.2 # In Python 3.6, its latest version supported is 6.2. But it supports 6.4 version in Python 3.10. codecov >= 2.1.12 coveralls >= 3.3.1 + +## For running HTTP server for testing crawling feature of web spider +flask >= 2.0.0 +gunicorn >= 20.0.0 diff --git a/scripts/ci/build_git-tag_or_create_github-release.sh b/scripts/ci/build_git-tag_or_create_github-release.sh new file mode 100644 index 00000000..5ea2a92e --- /dev/null +++ b/scripts/ci/build_git-tag_or_create_github-release.sh @@ -0,0 +1,312 @@ +#!/usr/bin/env bash + +#set -ex + +# Check whether it has 'release-notes.md' or 'release-title.md' in the target directory '.github'. +has_auto_release_flag=$(ls .github | grep -E "release-auto-flag.txt") +if [ "$has_auto_release_flag" == "" ]; then + echo "โš ๏ธ It should have *release-auto-flag.txt* in '.github' directory of your project in HitHub." + exit 0 +else + auto_release_flag=$(cat .github/release-auto-flag.txt) + if [ "$auto_release_flag" == false ]; then + echo "๐Ÿ’ค Auto-release flag is 'false' so it won't build git tag or create GitHub release." + exit 0 + fi +fi + +has_release_notes=$(ls .github | grep -E "release-notes.md") +has_release_title=$(ls .github | grep -E "release-title.md") +if [ "$has_release_notes" == "" ]; then + echo "โŒ It should have *release-notes.md* in '.github' directory of your project in HitHub." + exit 1 +fi +if [ "$has_release_title" == "" ]; then + echo "โŒ It should have *release-title.md* in '.github' directory of your project in HitHub." + exit 1 +fi + + +# # # # python-package or github-action-reusable-workflow +Input_Arg_Release_Type=$1 +Input_Arg_Debug_Mode=$2 + +if [ "$Input_Arg_Release_Type" == "" ]; then + echo "โŒ The argument 'Input_Arg_Release_Type' (first argument) cannot be empty." + exit 1 +fi + +if [ "$Input_Arg_Release_Type" == 'python-package' ]; then + # # # # The name of Python package + Input_Arg_Python_Pkg_Name=$3 + # # # # For development and troubleshooting +# Input_Arg_Debug_Mode=$4 + Input_Arg_Software_Version_Format=$4 +elif [ "$Input_Arg_Release_Type" == 'github-action-reusable-workflow' ]; then + Input_Arg_Python_Pkg_Name="" + Input_Arg_Software_Version_Format="" +# Input_Arg_Debug_Mode=$2 +else + echo "โŒ Currently, it only has 2 release type: 'python-package' or 'github-action-reusable-workflow'." + exit 1 +fi +if [ "$Input_Arg_Debug_Mode" == "" ]; then + Input_Arg_Debug_Mode=true +fi + + +# # # # From the PEP440: Software version style rule +# # # +# # # The version setting 1: version format +# # Simple โ€œmajor.minorโ€ versioning: (general-2) +# 0.1, 0.2, 0.3, 1.0, 1.1 +# # Simple โ€œmajor.minor.microโ€ versioning: (general-3) +# 1.0.0, 1.0.1, 1.0.2, 1.1.0 +# # Date based releases, using an incrementing serial within each year, skipping zero: (date-based) +# 2012.1, 2012.2, ..., 2012.15, 2013.1, 2013.2 +# # # The version setting 2: version evolution +# # โ€œmajor.minorโ€ versioning with alpha, beta and candidate pre-releases: (sema) +# 0.9, 1.0a1, 1.0a2, 1.0b1, 1.0rc1, 1.0 +# # โ€œmajor.minorโ€ versioning with developmental releases, release candidates and post-releases for minor corrections: (dev) +# 0.9, 1.0.dev1, 1.0.dev2, 1.0.dev3, 1.0c1, 1.0, 1.0.post1, 1.1.dev1 +#Input_Arg_Software_Version_Format=$3 + +declare Software_Version_Reg +declare Python_Version_Reg + +if [ "$Input_Arg_Release_Type" == 'python-package' ]; then + + if [ "$Input_Arg_Python_Pkg_Name" == "" ]; then + echo "โŒ The argument 'Input_Arg_Python_Pkg_Name' (second argument) cannot be empty if option 'Input_Arg_Release_Type' (first argument) is 'python-package'." + exit 1 + fi + + declare version_reg + if [ "$Input_Arg_Software_Version_Format" == "general-2" ]; then + version_reg="[0-9]\.[0-9]" + elif [ "$Input_Arg_Software_Version_Format" == "general-3" ]; then + version_reg="[0-9]\.[0-9]\.[0-9]" + elif [ "$Input_Arg_Software_Version_Format" == "date-based" ]; then + version_reg="[0-9]{4}\.([0-9]{1,})+" + else + # Default value + version_reg="[0-9]\.[0-9]\.[0-9]" + fi + + Software_Version_Reg="$version_reg*([\.,-]*([a-zA-Z]{1,})*([0-9]{0,})*){0,}" + Python_Version_Reg="__version__ = \"$Software_Version_Reg\"" + +fi + +#if [ "$Input_Arg_Release_Type" == 'python-package' ]; then +# if [ "$software_version_evolution" == "sema" ]; then +# echo "*-*([a-zA-Z]{1,})*([0-9]{0,})" +# elif [ "$software_version_evolution" == "dev" ]; then +# echo "*[\.,-]*([a-zA-Z]{1,})*([0-9]{0,})" +# else +# # Default value +# echo "" +# fi +#fi + + +#Current_Branch=$(git branch --show-current) +# # # # For debug +#echo "Verify the git branch info" +#git branch --list | cat +#echo "Verify all the git branch info" +#git branch -a | cat +#echo "Verify the git remote info" +#git remote -v +#echo "Get the current git branch info" + +# This is the global value to provide after-handle to use +Current_Branch=$(git branch --list | cat | grep -E '\* ([a-zA-Z0-9]{1,16})' | grep -E -o '([a-zA-Z0-9]{1,16})') +echo "๐Ÿ”Ž ๐ŸŒณ Current git branch: $Current_Branch" + +git config --global user.name "Chisanan232" +git config --global user.email "chi10211201@cycu.org.tw" +git_global_username=$(git config --global user.name) +git_global_user_email=$(git config --global user.email) +echo "๐Ÿ”Ž ๐ŸŒณ Current git name: $git_global_username" +echo "๐Ÿ”Ž ๐ŸŒณ Current git email: $git_global_user_email" + +declare Tag_Version # This is the return value of function 'get_latest_version_by_git_tag' +get_latest_version_by_git_tag() { + # # # # The types to get version by tag: 'git' or 'github' + get_version_type=$1 + + if [ "$get_version_type" == "git" ]; then + echo "๐Ÿ”Ž ๐ŸŒณ ๐Ÿท Get the version info from git tag." + Tag_Version=$(git describe --tag --abbrev=0 --match "v[0-9]\.[0-9]\.[0-9]*" | grep -E -o '[0-9]\.[0-9]\.[0-9]*') + elif [ "$get_version_type" == "github" ]; then + echo "๐Ÿ”Ž ๐Ÿ™ ๐Ÿˆ ๐Ÿท Get the version info from GitHub release." + github_release=$(curl -s https://api.github.com/repos/Chisanan232/GitHub-Action_Workflow-Template-Python/releases/latest | jq -r '.tag_name') + Tag_Version=$(echo "$github_release" | grep -E -o '[0-9]\.[0-9]\.[0-9]*') + else + echo "โŒ Currently, it only has 2 valid options could use: 'git' or 'github'." + exit 1 + fi +} + + +declare New_Release_Version # This is the return value of function 'generate_new_version_as_tag' +declare New_Release_Tag # This is the return value of function 'generate_new_version_as_tag' +generate_new_version_as_tag() { + project_type=$1 + if [ "$project_type" == "python" ]; then + echo "๐Ÿ”Ž ๐Ÿ ๐Ÿ“ฆ Get the new version info from Python package." + New_Release_Version=$(cat ./"$Input_Arg_Python_Pkg_Name"/__pkg_info__.py | grep -E "$Python_Version_Reg" | grep -E -o "$Software_Version_Reg") + elif [ "$project_type" == "github-action_reusable-workflow" ]; then + echo "๐Ÿ”Ž ๐Ÿ™ ๐Ÿˆ ๐Ÿท Get the current version info from GitHub release." + # Generate the new version from previous tag + get_latest_version_by_git_tag 'github' + current_ver=$(echo "$Tag_Version" | head -n1 | cut -d "." -f1) + echo "๐Ÿ”Ž ๐Ÿ“ƒ Current Version: $current_ver" + +# current_ver=$(git describe --tag --abbrev=0 --match "v[0-9]\.[0-9]\.[0-9]" | grep -E -o '[0-9]\.[0-9]\.[0-9]' | head -n1 | cut -d "." -f1) + if [ "$current_ver" == "" ]; then + current_ver=0 + fi + New_Release_Version=$(( current_ver + 1 )) + fi + + New_Release_Tag='v'$New_Release_Version'.0.0' +} + + +build_git_tag_or_github_release() { + # git event: push + # all branch -> Build tag + # master branch -> Build tag and create release + + project_type=$1 + generate_new_version_as_tag "$project_type" + + if [ "$Input_Arg_Debug_Mode" == true ]; then + echo " ๐Ÿ”๐Ÿ‘€ [DEBUG MODE] Build git tag $New_Release_Tag in git branch '$Current_Branch'." + else + git tag -a "$New_Release_Tag" -m "$New_Release_Tag" + git push -u origin --tags + fi + echo "๐ŸŽ‰ ๐Ÿป ๐ŸŒณ ๐Ÿท Build git tag which named '$New_Release_Tag' with current branch '$Current_Branch' successfully!" + + if [ "$Current_Branch" == "master" ]; then + release_title=$(cat .github/release-title.md) + + if [ "$Input_Arg_Debug_Mode" == true ]; then + echo " ๐Ÿ”๐Ÿ‘€ [DEBUG MODE] Create GitHub release with tag '$New_Release_Tag' and title '$release_title' in git branch '$Current_Branch'." + else + gh release create "$New_Release_Tag" --title "$release_title" --notes-file .github/release-notes.md + fi + fi + echo "๐ŸŽ‰ ๐Ÿป ๐Ÿ™ ๐Ÿˆ ๐Ÿท Create GitHub release with title '$release_title' successfully!" +} + + +# The truly running implementation of shell script +if [ "$Input_Arg_Release_Type" == 'python-package' ]; then + + # # # # For Python package release + echo "๐Ÿƒโ€โ™‚ ๏ธ๐Ÿ ๐Œš Run python package releasing process" + + git_tag=$(git describe --tag --abbrev=0 --match "v[0-9]\.[0-9]\.[0-9]*" | grep -o '[0-9]\.[0-9]\.[0-9]*') + github_release=$(curl -s https://api.github.com/repos/Chisanan232/GitHub-Action_Workflow-Template-Python/releases/latest | jq -r '.tag_name') + # shellcheck disable=SC2002 + generate_new_version_as_tag "python" + + build_git_tag=false + create_github_release=false + + # 1. Compare the Python source code version and git tag, GitHub release version. + if [ "$New_Release_Version" == "$git_tag" ]; then + echo "โœ… Version of git tag info are the same. So it verifies it has built and pushed before." + else + echo "โš ๏ธ Version of git tag info are different. So it verifies it doesn't build and push before." + build_git_tag=true + fi + + if [ "$Current_Branch" == "master" ] && [ "$New_Release_Version" == "$github_release" ]; then + echo "โœ… Version of GitHub release info are the same. So it verifies it has built and pushed before." + else + echo "โš ๏ธ Version of GitHub release info are different. So it verifies it doesn't build and push before." + create_github_release=true + fi + + # 1. -> Same -> 1-1. Does it have built and pushed before?. + # 1. -> No (In generally, it should no) -> 1-2. Is it a pre-release version in source code? + + # 1-1. Yes, it has built and pushed. -> Doesn't do anything. + # 1-1. No, it doesn't build and push before. -> Build and push directly. + + # 1-2. Yes, it's pre-release. -> Doesn't build and push. Just build git tag and GitHub release. + # 1-2. No, it's not pre-release. -> It means that it's official version, e.g., 1.3.2 version. So it should build git tag and GitHub release first, and build and push. + + if [ "$build_git_tag" == true ] || [ "$create_github_release" == true ]; then + + echo "๐Ÿ”Ž ๐Ÿ ๐Ÿ“ฆ Python package new release version: $New_Release_Version" + is_pre_release_version=$(echo $New_Release_Version | grep -E -o '([\.-]*([a-zA-Z]{1,})+([0-9]{0,})*){1,}') + echo "๐Ÿ”Ž ๐Ÿคฐ ๐Ÿ“ฆ is pre-release version: $is_pre_release_version" + if [ "$is_pre_release_version" == "" ]; then + echo "๐ŸŽ“ ๐Ÿ ๐Ÿ“ฆ The version is a official-release." + # do different things with different ranches + # git event: push + # all branch -> Build tag + # master branch -> Build tag and create release + echo "๐Ÿ‘ท๐Ÿฝโ€โ™‚๏ธ ๐Ÿ“Œ Build tag and create GitHub release, also push code to PyPi" + build_git_tag_or_github_release "python" + echo "โœ… ๐ŸŽŠ ๐Ÿฅ‚ Done! This is Official-Release so please push source code to PyPi." + echo "[Python] [Final Running Result] Official-Release" + else + echo "The version is a pre-release." + # do different things with different ranches + # git event: push + # all branch -> Build tag + # master branch -> Build tag and create release + echo "๐Ÿ‘ท๐Ÿฝโ€โ™‚ ๏ธ๐Ÿ“Œ Build tag and create GitHub release only" + build_git_tag_or_github_release "python" + echo "โœ… ๐ŸŽŠ ๐Ÿฅ‚ Done! This is Pre-Release so please don't push this to PyPi." + echo "[Python] [Final Running Result] Pre-Release" + fi + + fi + +elif [ "$Input_Arg_Release_Type" == 'github-action-reusable-workflow' ]; then + + echo "๐Ÿƒโ€โ™‚ ๐Ÿ™ ๐Ÿˆ ๐Œš Run github-action-reusable-workflow releasing process" + # # # # For GitHub Action reusable workflow template release + # 1. Compare whether the release-notes.md has different or not. + # Note 1: Diff a specific file with currently latest tag and previous one commit + # https://stackoverflow.com/questions/3338126/how-do-i-diff-the-same-file-between-two-different-commits-on-the-same-branch + # Note 2: Show the output result in stdout directly + # https://stackoverflow.com/questions/17077973/how-to-make-git-diff-write-to-stdout + # Note 3: Here code should be considered what git tag on master branch so we need to verify the info on master branch. + # Note 4: We should git fetch to provide git diff feature working + # https://github.com/actions/checkout/issues/160 + + echo "๐ŸŒณ โ›“ ๐ŸŒณ Run git fetch to sync upstream with latest project in GitHub" + git fetch --no-tags --prune --depth=1 origin +refs/heads/*:refs/remotes/origin/* + + echo "๐Ÿ”Ž ๐ŸŒณ ๐ŸŒณ Verify all the git branch info again after git fetch." + git branch -a | cat + + echo "๐Ÿ”Ž ๐Ÿ”— ๐ŸŒณ Verify the git remote info again after git fetch." + git remote -v + + echo "๐Ÿ”ฌ ๐Ÿ“„ ๐ŸŒณ โ›“ ๐ŸŒณ Check the different of '.github/release-notes.md' between current git branch and master branch ..." + release_notes_has_diff=$(git diff origin/master "$Current_Branch" -- .github/release-notes.md | cat) + echo "๐Ÿ”Ž ๐Ÿ”ฌ ๐Ÿ“„ different of '.github/release-notes.md': $release_notes_has_diff" + + if [ "$release_notes_has_diff" != "" ]; then + # 1. Yes, it has different. -> Build git tag, GitHub release and version branch + build_git_tag_or_github_release "github-action_reusable-workflow" + echo "โœ… ๐ŸŽŠ ๐Ÿฅ‚ Done! This is Official-Release of GitHub Action reusable workflow, please create a version branch of it." + echo "[GitHub Action - Reusable workflow] [Final Running Result] Official-Release and version: $New_Release_Version" + else + # 1. No, do nothing. + # Return nothing output + echo "๐Ÿ’ค Release note file doesn't change. Don't do anything." + echo "[GitHub Action - Reusable workflow] [Final Running Result] Pre-Release" + fi + +fi diff --git a/scripts/ci/check-input-params.sh b/scripts/ci/check-input-params.sh new file mode 100644 index 00000000..15dcce75 --- /dev/null +++ b/scripts/ci/check-input-params.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +#set -ex +upload_report_to_platform_flag=$1 +platform_token=$2 + +echo "๐Ÿ” Start to check input parameters ..." +if [ "$upload_report_to_platform_flag" = true ]; then + echo "โœ… This using flag of uploading platform is true." + if [ "$platform_token" = "" ]; then + echo "โš ๏ธ๏ธ The using flag of uploading to platform is true but it has no Token of it." + echo "โŒ It needs a Token to let CI could use it authenticates and uploads report to the platform. Please configure a Token to it." + exit 1 + else + echo "๐Ÿป It has a Token!" + fi +else + echo "๐Ÿ’ค It doesn't upload report to this platform." +fi diff --git a/scripts/ci/check_getting_output.sh b/scripts/ci/check_getting_output.sh new file mode 100644 index 00000000..cd5ff6b8 --- /dev/null +++ b/scripts/ci/check_getting_output.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +#set -ex + +release_version=$(echo $RELEASE_TYPE) +if [ "$release_version" != "" ]; then + echo "๐Ÿ“ฌ๐ŸŽ‰๐Ÿป It gets data which is release version info!" + exit 0 +else + echo "๐Ÿ“ญ๐Ÿ™ˆ It doesn't get any data which is release version info." + exit 1 +fi diff --git a/scripts/ci/deployment_new_version_workflow.sh b/scripts/ci/deployment_new_version_workflow.sh new file mode 100644 index 00000000..5d91f92e --- /dev/null +++ b/scripts/ci/deployment_new_version_workflow.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +debug_mode=$1 + +final_release_type=$RELEASE_TYPE +if [ "$final_release_type" == "Pre" ]; then + echo "๐Ÿ’ค It detects Pre-Release flag. So it does NOT do anything in deployment process." +else + echo "๐Ÿ“ฌ It detects Official-Release flag." + if [ "$debug_mode" == true ]; then + echo " ๐Ÿ”๐Ÿ‘€[DEBUG MODE] Create new git branch for the new version $final_release_type." + else + git remote add github-action_workflow-template https://github.com/Chisanan232/GitHub-Action-Template-Python.git + echo "๐Ÿ”—๐Ÿ“„ Add git remote reference." + git remote -v + echo "๐Ÿ” Check all git remote reference." + git checkout -b "v$final_release_type" + echo "โ›“ Create a new git branch as version." + git push -u github-action_workflow-template "v$final_release_type" + echo "๐Ÿป๐ŸŽ‰ Push the source code as a branch with one specific version to the GitHub." + fi +fi + +echo "๐ŸŽŠ๐Ÿฅ‚ Done!" diff --git a/scripts/ci/get-integration-test-paths.sh b/scripts/ci/test/get-integration-test-paths.sh similarity index 100% rename from scripts/ci/get-integration-test-paths.sh rename to scripts/ci/test/get-integration-test-paths.sh diff --git a/scripts/ci/get-unit-test-paths.sh b/scripts/ci/test/get-unit-test-paths.sh similarity index 100% rename from scripts/ci/get-unit-test-paths.sh rename to scripts/ci/test/get-unit-test-paths.sh diff --git a/test/_http_server/app.py b/test/_http_server/app.py new file mode 100644 index 00000000..896856ef --- /dev/null +++ b/test/_http_server/app.py @@ -0,0 +1,61 @@ +""" +A simple HTTP server for testing. It would return a JSON type data. +""" + +from flask import Flask, request + + +app: Flask = Flask(__name__) + + +@app.route("/exchangeReport/STOCK_DAY", methods=["GET"]) +def get_stock_data() -> str: + """ + API: /exchangeReport/STOCK_DAY + API Parameters: + * response: The data format. Default is JSON type. + * date: The date of data. + * stockNo: The stock symbol no. + + Example: + http://10.20.23.3:12345/exchangeReport/STOCK_DAY?response=json&date=20170101&stockNo=2330 + + :return: A string type data with JSON type format. + """ + + _response = request.args.get("response", "json") + _date = request.args.get("date", None) # Example: 20170101 + _stockNo = request.args.get("stockNo", None) # Example: 2330 + + _data = '{' \ + '"stat":"OK",' \ + f'"date":"{_date}",' \ + f'"title":"111ๅนด06ๆœˆ {_stockNo} ๅฐ็ฉ้›ป ๅ„ๆ—ฅๆˆไบค่ณ‡่จŠ",' \ + '"fields":["ๆ—ฅๆœŸ","ๆˆไบค่‚กๆ•ธ","ๆˆไบค้‡‘้ก","้–‹็›คๅƒน","ๆœ€้ซ˜ๅƒน","ๆœ€ไฝŽๅƒน","ๆ”ถ็›คๅƒน","ๆผฒ่ทŒๅƒนๅทฎ","ๆˆไบค็ญ†ๆ•ธ"],' \ + '"data":[' \ + '["111/06/01","32,970,903","18,171,598,472","550.00","555.00","548.00","549.00","-11.00","33,456"],' \ + '["111/06/02","26,063,495","14,122,936,388","544.00","545.00","540.00","540.00","-9.00","30,042"],' \ + '["111/06/06","23,732,327","12,843,324,209","541.00","544.00","538.00","540.00"," 0.00","16,614"],' \ + '["111/06/07","22,152,512","11,846,386,906","535.00","538.00","532.00","535.00","-5.00","28,586"],' \ + '["111/06/08","19,609,522","10,636,701,303","539.00","545.00","538.00","544.00","+9.00","18,487"],' \ + '["111/06/09","16,894,479","9,115,934,006","538.00","542.00","537.00","541.00","-3.00","18,802"],' \ + '["111/06/10","22,614,596","12,011,615,014","530.00","533.00","529.00","530.00","-11.00","44,802"],' \ + '["111/06/13","36,758,925","18,998,155,460","518.00","519.00","515.00","516.00","-14.00","112,023"],' \ + '["111/06/14","38,838,778","19,813,036,892","507.00","514.00","507.00","513.00","-3.00","85,483"],' \ + '["111/06/15","38,360,508","19,580,150,319","508.00","515.00","508.00","509.00","-4.00","72,687"],' \ + '["111/06/16","31,908,028","16,331,470,764","515.00","516.00","507.00","508.00","X0.00","42,177"],' \ + '["111/06/17","48,400,798","24,260,277,915","499.50","503.00","499.00","501.00","-7.00","119,618"],' \ + '["111/06/20","36,664,463","18,267,359,790","500.00","502.00","495.00","498.00","-3.00","89,541"],' \ + '["111/06/21","34,432,537","17,298,234,720","501.00","505.00","499.00","505.00","+7.00","32,427"],' \ + '["111/06/22","33,438,921","16,630,857,096","501.00","503.00","494.50","494.50","-10.50","81,024"],' \ + '["111/06/23","46,808,462","22,836,692,325","492.00","493.50","485.00","485.50","-9.00","104,661"],' \ + '["111/06/24","29,003,676","14,184,287,155","489.50","492.50","485.50","486.50","+1.00","43,609"],' \ + '["111/06/27","38,684,368","19,379,396,938","496.00","506.00","495.50","498.50","+12.00","37,438"],' \ + '["111/06/28","16,867,955","8,392,290,378","496.00","500.00","496.00","497.50","-1.00","18,988"],' \ + '["111/06/29","33,124,986","16,352,376,816","496.00","498.50","491.00","491.00","-6.50","40,024"],' \ + '["111/06/30","49,820,824","23,900,613,642","484.50","486.50","476.00","476.00","-15.00","111,117"]' \ + '],' \ + '"notes":["็ฌฆ่™Ÿ่ชชๆ˜Ž:+/-/X่กจ็คบๆผฒ/่ทŒ/ไธๆฏ”ๅƒน","็•ถๆ—ฅ็ตฑ่จˆ่ณ‡่จŠๅซไธ€่ˆฌใ€้›ถ่‚กใ€็›คๅพŒๅฎšๅƒนใ€้‰…้กไบคๆ˜“๏ผŒไธๅซๆ‹่ณฃใ€ๆจ™่ณผใ€‚","ETF่ญ‰ๅˆธไปฃ่™Ÿ็ฌฌๅ…ญ็ขผ็‚บKใ€Mใ€Sใ€C่€…๏ผŒ่กจ็คบ่ฉฒETFไปฅๅค–ๅนฃไบคๆ˜“ใ€‚"]' \ + '}' + return _data + diff --git a/test/_http_server/test_data.json b/test/_http_server/test_data.json new file mode 100644 index 00000000..1836797a --- /dev/null +++ b/test/_http_server/test_data.json @@ -0,0 +1,24 @@ +{ + "stat":"OK", + "date":"20220820", + "title":"111ๅนด08ๆœˆ 2330 ๅฐ็ฉ้›ป ๅ„ๆ—ฅๆˆไบค่ณ‡่จŠ", + "fields":["ๆ—ฅๆœŸ","ๆˆไบค่‚กๆ•ธ","ๆˆไบค้‡‘้ก","้–‹็›คๅƒน","ๆœ€้ซ˜ๅƒน","ๆœ€ไฝŽๅƒน","ๆ”ถ็›คๅƒน","ๆผฒ่ทŒๅƒนๅทฎ","ๆˆไบค็ญ†ๆ•ธ"], + "data":[ + ["111/08/01","24,991,291","12,569,771,761","506.00","508.00","500.00","504.00","-5.00","26,792"], + ["111/08/02","42,669,591","20,973,293,337","494.00","496.00","488.50","492.00","-12.00","63,879"], + ["111/08/03","29,838,832","14,823,224,632","494.00","501.00","493.00","501.00","+9.00","25,570"], + ["111/08/04","26,589,086","13,279,624,282","499.00","503.00","495.00","500.00","-1.00","27,173"], + ["111/08/05","35,052,642","17,966,410,242","509.00","516.00","507.00","516.00","+16.00","49,928"], + ["111/08/08","20,568,971","10,531,710,250","510.00","515.00","509.00","512.00","-4.00","18,131"], + ["111/08/09","24,370,709","12,372,442,661","507.00","511.00","504.00","510.00","-2.00","25,433"], + ["111/08/10","22,112,239","11,075,581,424","500.00","503.00","499.50","500.00","-10.00","35,188"], + ["111/08/11","24,906,177","12,771,121,611","513.00","514.00","510.00","514.00","+14.00","23,949"], + ["111/08/12","21,343,450","11,016,097,043","515.00","518.00","514.00","517.00","+3.00","21,701"], + ["111/08/15","22,519,886","11,755,494,600","520.00","524.00","519.00","523.00","+6.00","27,372"], + ["111/08/16","21,234,122","11,141,160,337","526.00","526.00","523.00","525.00","+2.00","20,628"], + ["111/08/17","28,461,939","14,943,047,011","524.00","527.00","521.00","527.00","+2.00","26,466"], + ["111/08/18","18,721,898","9,734,756,997","520.00","521.00","519.00","520.00","-7.00","24,209"], + ["111/08/19","14,235,983","7,403,584,002","519.00","523.00","517.00","519.00","-1.00","14,069"] + ], + "notes":["็ฌฆ่™Ÿ่ชชๆ˜Ž:+/-/X่กจ็คบๆผฒ/่ทŒ/ไธๆฏ”ๅƒน","็•ถๆ—ฅ็ตฑ่จˆ่ณ‡่จŠๅซไธ€่ˆฌใ€้›ถ่‚กใ€็›คๅพŒๅฎšๅƒนใ€้‰…้กไบคๆ˜“๏ผŒไธๅซๆ‹่ณฃใ€ๆจ™่ณผใ€‚","ETF่ญ‰ๅˆธไปฃ่™Ÿ็ฌฌๅ…ญ็ขผ็‚บKใ€Mใ€Sใ€C่€…๏ผŒ่กจ็คบ่ฉฒETFไปฅๅค–ๅนฃไบคๆ˜“ใ€‚"] +} \ No newline at end of file diff --git a/test_gh_workflow/__pkg_info__.py b/test_gh_workflow/__pkg_info__.py new file mode 100644 index 00000000..02ca93b3 --- /dev/null +++ b/test_gh_workflow/__pkg_info__.py @@ -0,0 +1 @@ +__version__ = "0.2.0-alpha1.post1"