Release: development → main (version fix, TSC 0.41, mypy, bug fixes)#415
Open
jacalata wants to merge 36 commits into
Open
Release: development → main (version fix, TSC 0.41, mypy, bug fixes)#415jacalata wants to merge 36 commits into
jacalata wants to merge 36 commits into
Conversation
…#301) When `tabcmd login -u myuser` is run with no `-p` flag, the session creation now correctly prompts for a password interactively (or exits with an error if `--no-prompt` is set), rather than falling through to the saved-session path and failing with a missing-arguments error. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a user supplies -f output.csv with a URL that has a different extension (e.g. view.png), the file type is now determined from the user-supplied filename extension. If the filename has no recognized extension, or no filename is given, the URL extension is used as the fallback. Adds three tests covering the three cases. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace filename="tabcmd.log" in logging.basicConfig with a RotatingFileHandler (max 1 MB per file, 5 backups) so the log file no longer grows indefinitely. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
c:\dev\tabcmd>mypy tests tests\commands\test_projects_utils.py:22: error: Argument 1 to "_parse_project_path_to_list" of "Server" has incompatible type "None"; expected "str" [arg-type] tests\commands\test_user_utils.py:76: error: Incompatible types in assignment (expression has type "UserItem | None", variable has type "UserItem") [assignment] tests\commands\test_user_utils.py:84: error: Incompatible types in assignment (expression has type "UserItem | None", variable has type "UserItem") [assignment] tests\e2e\language_tests.py:208: error: "OnlineCommandTest" has no attribute "_get_workbook" [attr-defined] tests\e2e\tests_integration.py:68: error: Name "logger" is not defined [name-defined] tests\e2e\tests_integration.py:99: error: Name "logger" is not defined [name-defined] tests\e2e\tests_integration.py:133: error: Name "__class__" is not defined [name-defined] tests\commands\test_session.py:206: error: Argument 1 to "_allow_prompt" has incompatible type "Namespace"; expected "Session" [arg-type] tests\commands\test_session.py:211: error: Argument 1 to "_allow_prompt" has incompatible type "Namespace"; expected "Session" [arg-type] tests\commands\test_session.py:216: error: Argument 1 to "_allow_prompt" has incompatible type "Namespace"; expected "Session" [arg-type] Found 10 errors in 5 files (checked 51 source files)
output with fixes > mypy tests Success: no issues found in 51 source files
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- Replace basicConfig (no-op if root already has handlers) with an explicit setLevel on the root logger - Guard RotatingFileHandler and StreamHandler creation so repeated configure_log calls don't accumulate duplicate handlers - Add tests for no-duplicate and level-set behaviour Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add test covering the case where neither filename nor URL has a recognized extension, which should exit with an error. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The elif branch now only fires when there is no active session. If a session already exists (self.tableau_server is set), fall through to the existing-session reuse path instead of unconditionally signing out and prompting for a password. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Run black across all modified files - Convert PublishCommand.run_command from @staticmethod to @classmethod - Fix exit_with_error call passing list instead of str Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Satisfies mypy check_untyped_defs — local stub class doesn't structurally match the expected ProjectItem type, cast() avoids changing production code. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The session reuse path checks self.user_id before calling users.get_by_id; without it, validation always returns None and the test hits the missing- arguments error path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: show correct version in PyInstaller exe (W-22831646) importlib.metadata is unavailable inside PyInstaller bundles, causing tabcmd --version to always display the hardcoded fallback. Configure setuptools_scm to write tabcmd/_version.py at build time so PyInstaller bundles it; version.py falls back to that file instead of a hardcoded string. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: ensure _version.py is written by doit version before pyinstaller runs * test: verify version.py fallback import matches pyproject write_to path * fix: use 0.0 as last-resort version fallback (clearly wrong, but parseable) * fix: add assert narrowing to fix mypy union-attr error in test_version.py Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…fixes) (#416) * Bump actions/upload-artifact from 4 to 7 (#392) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](actions/upload-artifact@v4...v7) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump actions/checkout from 6 to 7 (#394) Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@v6...v7) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * ci: automate release pipeline - release-on-merge.yml: on push to main, auto-computes next patch version, pushes the git tag (which triggers package.yml to build binaries), and creates a draft GitHub release with auto-generated notes for human review before publishing - publish-pypi.yml: add release:published trigger so clicking "Publish release" in GitHub UI automatically uploads to PyPI; fix is_draft conditionals to work when triggered without inputs - run-e2-tests.yml: add workflow_call interface (inputs + secrets) so the e2e suite can be called from other workflows; move credentials to env vars to avoid shell injection - online_tests.py: set site_admin=False to match actual account permissions; add skip guard on test_delete_extract (requires extract encryption, not available on this site) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * ci: remove promote:true from package.yml to preserve draft state Binaries are now uploaded to the draft release created by release-on-merge.yml without auto-publishing it. Release stays draft until manually published, which then triggers PyPI upload. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * ci: address OSS security review findings - publish-pypi.yml: remove dead `push: tags: 'pypi'` trigger (secret publish path bypassing the draft-release gate); make publish conditionals explicit using github.event_name so the trigger surface is unambiguous rather than relying on null coercion - release-on-merge.yml: filter tags to strict semver regex before sorting (prevents arithmetic failure on malformed tags); fail loudly if no prior tag exists instead of silently defaulting to v2.0.1; align checkout to actions/checkout@v7 - online_tests.py: suppress argv printing when login args (including PAT token) are present, preventing credential leak in CI logs Tracking: #417 (PyPI trusted publishing / OIDC) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * ci: allow coverage comment step to fail on fork PRs MishaKav/pytest-coverage-comment@main updated and now fails with permission denied on fork PRs (GITHUB_TOKEN is read-only for pull_request events from forks). Coverage is still collected and reported; only the PR comment step fails. Mark it continue-on-error so CI stays green. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * ci: make e2e permission flags configurable via workflow inputs Previously server_admin/site_admin/project_admin/extract_encryption_enabled were hardcoded in online_tests.py. Now they are read from env vars (E2E_SITE_ADMIN, E2E_SERVER_ADMIN, E2E_PROJECT_ADMIN, E2E_EXTRACT_ENCRYPTION) so callers can enable the relevant test groups for their account permissions. workflow_dispatch: adds optional boolean choice inputs for each flag workflow_call: adds optional boolean inputs (default false) online_tests.py: reads flags from env via _env_bool(), defaults unchanged Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test: skip e2e tests gracefully when credentials.py is absent Previously get_login_args() raised AttributeError when credentials.py was not present (ImportError silently set credentials = {}). Now returns None and _test_command skips with a clear message instead of crashing. Also removes redundant second call to get_login_args() in _test_command. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * style: black formatting for e2e test files Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: fall back to E2E_* env vars in get_login_args() when credentials.py is absent Without this, CI always skips the e2e suite because credentials.py is not committed — even when E2E_SERVER/SITE/PATNAME/PAT are set via workflow inputs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Merges all accumulated development work into main for a new release.
Key changes since last main merge:
importlib.metadataunavailable in frozen bundles; fall back totabcmd/_version.pygenerated at build time (fix: show correct version in PyInstaller exe (W-22831646) #410, W-22831646)check_untyped_defs— full static type checking now enforced (mypy: enable checking untyped code #367)get_file_type_from_filename(--filename for get url function does not respect the file extension #256 / fix: use explicit extension check in get_file_type_from_filename (#256) #406)--usernamegiven without credentials (tabcmd login does not ask for the password if only the user is specified #301 / fix: prompt for password when --username given without credentials (#301) #405)Test plan
pytestpasses (317 passed, 2 skipped)python -m blackcleantabcmd.exe --version🤖 Generated with Claude Code