diff --git a/.github/actions/workflow-info/action.yaml b/.github/actions/workflow-info/action.yaml new file mode 100644 index 0000000..185b891 --- /dev/null +++ b/.github/actions/workflow-info/action.yaml @@ -0,0 +1,63 @@ +name: 'Report Workflow Information' +description: 'Reusable action meant to be used in workflow steps' +branding: + icon: 'watch' + color: 'green' + +inputs: + title: + description: 'A reference to put in the report title' + required: true + default: 'the Job' + parameters: + description: 'Input variables used in Job' + required: false + content: + description: 'Content to put in the report' + required: false +outputs: + status: + description: "Return report status" + value: ${{ steps.report_workflow_generation.outputs.status }} +runs: + using: "composite" + steps: + - name: Report Workflow Information + id: report_workflow_generation + env: + REPORT_PARAMS: '${{ inputs.parameters }}' + REPORT_CONTENT: '${{ inputs.content }}' + shell: bash + run: | + echo "::group::Generating report" + echo "status=started" >> "${GITHUB_OUTPUT}"; + + dump_ctx(){ + echo "::group::Context ${1:-Unknown}" + local text; + if ! text="$(cat -)"; then printf 'Failed to dump context for %s\n' "${1:-Unknown}" >> "${GITHUB_STEP_SUMMARY}"; fi + text="${text#"${text%%[![:space:]]*}"}" + if test "${#text}" -gt 3; then + printf '\n### %s Context\n\n\n```json\n%s\n```\n' "${1:-Unknown}" "${text:-Nothing in context}" >> "${GITHUB_STEP_SUMMARY}"; + fi + echo "::endgroup::"; + }; + + printf '# Workflow Information on ${{ inputs.title }}\n\n' >> "${GITHUB_STEP_SUMMARY}"; + printf '\n## Event Information\n\n' >> "${GITHUB_STEP_SUMMARY}"; + echo '- github.ref_name: ${{ github.ref_name }}' >> "${GITHUB_STEP_SUMMARY}"; + echo '- github.sha: ${{ github.sha }}' >> "${GITHUB_STEP_SUMMARY}"; + + echo "${REPORT_PARAMS:-}" | dump_ctx "Parameters"; + if test -n "${REPORT_CONTENT:-}"; then + printf '\n## Summary\n\n' >> "${GITHUB_STEP_SUMMARY}"; + echo "${REPORT_CONTENT:-}" >> "${GITHUB_STEP_SUMMARY}"; + fi + + printf '\n## Context Information\n' >> "${GITHUB_STEP_SUMMARY}"; + echo '${{ toJson(runner) }}' | dump_ctx "Runner"; + echo '${{ toJson(job) }}' | dump_ctx "Job"; + + echo "status=finished" >> "${GITHUB_OUTPUT}"; + echo "::endgroup::" + diff --git a/.github/workflows/testing_changes.yml b/.github/workflows/testing_changes.yml index b3a3e2f..d153dc7 100644 --- a/.github/workflows/testing_changes.yml +++ b/.github/workflows/testing_changes.yml @@ -4,12 +4,10 @@ name: testing_changes on: push: - branches-ignore: - - 'main' - - 'master' - - 'draft/*' + branches: [ "master" ] pull_request: - types: [opened, reopened, synchronize] + branches: [ "master" ] + types: [opened, reopened, synchronize, ready_for_review] release: types: [created, edited] workflow_dispatch: @@ -62,45 +60,123 @@ jobs: ci: name: ci-testing_changes strategy: - # max-parallel: 1 + fail-fast: false matrix: - target: [latest, 5, 5.0.2, 5-noble, 5-jammy, 4, 4.0.5, 3, 3.0.12] - os: [ "ubuntu-latest" ] - #TODO: os: [ "ubuntu-latest", "windows-latest", "macos-latest" ] + os: [ "ubuntu-latest", "windows-latest", "macos-latest", "macos-13" ] + # ubuntu-latest: https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md + # macos-latest: https://github.com/actions/runner-images/blob/main/images/macos/macos-15-arm64-Readme.md + # macos-13: https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md + # windows-latest: https://github.com/actions/runner-images/blob/main/images/windows/Windows2022-Readme.md + target: [ 'latest', '5', '5.0.2', '5-noble', '5-jammy', '4', '4.0.5', '3', '3.0.12' ] + # https://github.com/FirebirdSQL/firebird-docker runs-on: "${{ matrix.os }}" steps: - - name: Checkout source code on event ${{ github.event_name }} triggered by '${{ github.sha }}' - if: github.event_name != 'release' - uses: actions/checkout@v3 - - - name: Testing changes with FirebirdSQL version ${{ matrix.target }} on ${{ github.event_name }} triggered by '${{ github.sha }}' - if: github.event_name != 'release' - uses: ./ # Uses an action in the root directory + - name: Testing release with FirebirdSQL version ${{ matrix.target }} triggered by version '${{ github.event.release.tag_name }}' + if: github.event_name == 'release' && matrix.os == 'ubuntu-latest' + uses: juarezr/firebirdsql-github-action@master with: version: '${{ matrix.target }}' firebird_database: 'my_database.fdb' firebird_user: 'my_user' firebird_password: 'my_password' - - name: Testing release with FirebirdSQL version ${{ matrix.target }} triggered by version '${{ github.event.release.tag_name }}' - if: github.event_name == 'release' - uses: juarezr/firebirdsql-github-action@master + - name: Checkout source code on event ${{ github.event_name }} triggered by '${{ github.sha }}' + if: github.event_name != 'release' + uses: actions/checkout@v3 + + - name: Report Workflow Information + id: workflow_report + uses: ./.github/actions/workflow-info + with: + title: '${{ github.ref_name }}' + parameters: '${{ toJson(inputs) }}' + content: | + - Ref: ${{ github.head_ref }} + + - name: Setup docker (missing on MacOS) on ${{ matrix.os }} + if: runner.os == 'macos' + uses: docker-practice/actions-setup-docker@master + timeout-minutes: 12 + + - name: Report Docker Information on ${{ matrix.os }} + shell: bash + run: | + echo "::group::Step Report" + printf '## Docker Version on ${{ matrix.os }}\n\n' >> "${GITHUB_STEP_SUMMARY}"; + docker --version >> "${GITHUB_STEP_SUMMARY}"; + printf '## Docker Configuration on ${{ matrix.os }}\n\n' >> "${GITHUB_STEP_SUMMARY}"; + docker version >> "${GITHUB_STEP_SUMMARY}"; + echo "::endgroup::" + + - name: Testing changes with FirebirdSQL version ${{ matrix.target }} on ${{ matrix.os }} triggered by '${{ github.event_name }}' + if: github.event_name != 'release' && matrix.os == 'ubuntu-latest' + uses: ./ # Uses an action in the root directory with: version: '${{ matrix.target }}' firebird_database: 'my_database.fdb' firebird_user: 'my_user' firebird_password: 'my_password' + - name: Switch to Linux Containers on '${{ matrix.os }}' + if: github.event_name != 'release' && matrix.os == 'windows-latest' + shell: bash + run: | + docker --help + command -v docker || true + command -v dockercli || true + command -v DockerCli || true + command -v DockerCli.exe || true + pwd + ls -l "/c/" + ls -l /c/Windows/system32/Do* + /c/Windows/system32/DockerCli.exe -SwitchLinuxEngine + + - name: Testing changes with FirebirdSQL version ${{ matrix.target }} on '${{ matrix.os }}' + if: github.event_name != 'release' && matrix.os != 'ubuntu-latest' + shell: bash + run: | + export INPUT_CONTAINER_NAME='firebirdsql' + export INPUT_FIREBIRD_DATABASE='localhost:/var/lib/firebird/data/my_database.fdb' + export INPUT_FIREBIRD_USER='my_user' + export INPUT_FIREBIRD_PASSWORD='my_password' + export INPUT_FIREBIRD_CONF='ConnectionTimeout=180,DeadlockTimeout=10' + echo "::group::Checkout Report" + echo "PWD: ${PWD:-}" + ls --escape --dereference-command-line --human-readable --time-style=iso --no-group --color=auto -la + echo "::endgroup::" + bash entrypoint.sh + - name: Install FirebirdSQL clients + if: matrix.os == 'ubuntu-latest' + shell: bash run: | sudo apt-get update sudo apt-get install -y --no-install-recommends firebird3.0-utils libfbclient2 - - name: Testing Connection and Query to ${{ matrix.target }} + - name: Wait for Firebird version ${{ matrix.target }} to be available on ${{ matrix.os }} + if: matrix.os == 'ubuntu-latest' + shell: bash run: | for i in {0..120} ; do nc -z localhost 3050 && echo "Up: ${i} secs" && break; sleep 1; done - echo 'select * from rdb$database;' | isql-fb -bail -quiet -z -user my_user -password my_password 'localhost:/var/lib/firebird/data/my_database.fdb' + + - name: Testing Connection and Query with FirebirdSQL version ${{ matrix.target }} + if: matrix.os == 'ubuntu-latest' + shell: bash + run: | + echo 'SELECT * FROM rdb$roles;' | isql-fb -bail -quiet -z -user my_user -password my_password 'localhost:/var/lib/firebird/data/my_database.fdb' + + - name: Install Python driver + shell: bash + run: | + python3 -m pip install --upgrade pip wheel + python3 -m pip install firebird-driver + python3 -m pip install rich typer + + - name: Testing Connection and Query with FirebirdSQL version ${{ matrix.target }} with python + shell: bash + run: | + python3 test_connection.py --user my_user --password my_password --host localhost /var/lib/firebird/data/my_database.fdb - name: Stop Container run: | diff --git a/test_connection.py b/test_connection.py new file mode 100755 index 0000000..cb175e7 --- /dev/null +++ b/test_connection.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# coding: utf-8 + +import typer + +from firebird.driver import connect, DESCRIPTION_NAME +from rich import print +from rich.table import Table + +app = typer.Typer() + +# region Commands ---------------------------------------------------------------------- + + +@app.command() +def connect_to_firebird( + database: str, + host: str = "localhost", + user: str = "sysdba", + password: str = "masterkey", + query: str = None, +) -> int: + """Attach to an existing database/alias using server connection to host""" + # @ See: https://firebird-driver.readthedocs.io/en/stable/getting-started.html#executing-sql-statements + + tab = Table("Query Results") + db = f"{host}:{database}" + + with connect(db, user=user, password=password) as con: + with con.cursor() as cursor: + print(f"Connected to {db}") + cursor.execute(query or "SELECT * FROM rdb$roles") + + for fieldDesc in cursor.description: + tab.add_column(fieldDesc[DESCRIPTION_NAME]) + + fieldIndices = range(len(cursor.description)) + for row in cursor: + cols = [] + for fieldIndex in fieldIndices: + fieldValue = str(row[fieldIndex]) + cols += [fieldValue] + tab.add_row(*cols) + + print(tab) + return 0 + + +# endregion + +# region Main --------------------------------------------------------------------------- + +if __name__ == "__main__": + app() + +# endregion diff --git a/testing.sh b/testing.sh index fcd8494..19b8d5b 100755 --- a/testing.sh +++ b/testing.sh @@ -65,11 +65,11 @@ for INPUT_VERSION in latest 5 5.0.2 5-noble 5-jammy 4 4.0.5 3 3.0.12; do msg "Querying the FirebirdSQL server inside the docker container at [${IP_ADDRESS}]..." # shellcheck disable=SC2016 - if ! echo 'SELECT * FROM rdb$database;' | + if ! echo 'SELECT * FROM rdb$roles;' | docker run -i --rm --name "${INPUT_CONTAINER_NAME}-client2" \ --network "${INPUT_NETWORK_NAME}" --env IP_ADDRESS="${IP_ADDRESS}" \ "firebirdsql/firebird:${INPUT_VERSION:-}" \ - sh -c isql -bail -quiet -echo -merge -m2 -z \ + sh -c isql -bail -quiet -z \ -user "${INPUT_FIREBIRD_USER}" -password "${INPUT_FIREBIRD_PASSWORD}" \ "${IP_ADDRESS}:${FIREBIRD_DATA}/${INPUT_FIREBIRD_DATABASE}" | ident; then