diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 138aa5de3..b86c2be84 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -57,7 +57,7 @@ body: description: Paste the output from the command above. This will be automatically formatted, so no need for backticks. render: shell placeholder: | - com.foundryvtt.version = "12.320" + com.foundryvtt.version = "13.332" org.opencontainers.image.authors = "markf+github@geekpad.com" org.opencontainers.image.created = "2022-09-01T23:22:04.337Z" org.opencontainers.image.description = "An easy-to-deploy Dockerized Foundry Virtual Tabletop server." @@ -67,7 +67,7 @@ body: org.opencontainers.image.title = "foundryvtt-docker" org.opencontainers.image.url = "https://github.com/felddy/foundryvtt-docker" org.opencontainers.image.vendor = "Geekpad" - org.opencontainers.image.version = "12.320.0" + org.opencontainers.image.version = "13.332.0" validations: required: true - type: textarea @@ -78,7 +78,7 @@ body: render: console placeholder: | foundry_1 | Entrypoint | 2022-02-23 14:14:53 | [debug] Timezone set to: US/Eastern - foundry_1 | Entrypoint | 2022-02-23 14:14:53 | [info] Starting felddy/foundryvtt container v12.320.0 + foundry_1 | Entrypoint | 2022-02-23 14:14:53 | [info] Starting felddy/foundryvtt container v13.332.0 foundry_1 | Entrypoint | 2022-02-23 14:14:53 | [debug] CONTAINER_VERBOSE set. Debug logging enabled. foundry_1 | Entrypoint | 2022-02-23 14:14:53 | [info] Reading configured secrets from: /run/secrets/config.json foundry_1 | Entrypoint | 2022-02-23 14:14:53 | [info] No Foundry Virtual Tabletop installation detected. diff --git a/.github/ISSUE_TEMPLATE/regression.yml b/.github/ISSUE_TEMPLATE/regression.yml index 2fd6dd3a5..96d1e6641 100644 --- a/.github/ISSUE_TEMPLATE/regression.yml +++ b/.github/ISSUE_TEMPLATE/regression.yml @@ -72,7 +72,7 @@ body: description: Paste the output from the command above. This will be automatically formatted, so no need for backticks. render: shell placeholder: | - com.foundryvtt.version = "12.320" + com.foundryvtt.version = "13.332" org.opencontainers.image.authors = "markf+github@geekpad.com" org.opencontainers.image.created = "2022-09-01T23:22:04.337Z" org.opencontainers.image.description = "An easy-to-deploy Dockerized Foundry Virtual Tabletop server." @@ -82,7 +82,7 @@ body: org.opencontainers.image.title = "foundryvtt-docker" org.opencontainers.image.url = "https://github.com/felddy/foundryvtt-docker" org.opencontainers.image.vendor = "Geekpad" - org.opencontainers.image.version = "12.320.0" + org.opencontainers.image.version = "13.332.0" validations: required: true - type: textarea @@ -93,7 +93,7 @@ body: render: console placeholder: | foundry_1 | Entrypoint | 2022-02-23 14:14:53 | [debug] Timezone set to: US/Eastern - foundry_1 | Entrypoint | 2022-02-23 14:14:53 | [info] Starting felddy/foundryvtt container v12.320.0 + foundry_1 | Entrypoint | 2022-02-23 14:14:53 | [info] Starting felddy/foundryvtt container v13.332.0 foundry_1 | Entrypoint | 2022-02-23 14:14:53 | [debug] CONTAINER_VERBOSE set. Debug logging enabled. foundry_1 | Entrypoint | 2022-02-23 14:14:53 | [info] Reading configured secrets from: /run/secrets/config.json foundry_1 | Entrypoint | 2022-02-23 14:14:53 | [info] No Foundry Virtual Tabletop installation detected. diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 70b2065f9..5117ccf84 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -15,6 +15,11 @@ updates: - "bot :robot:" - "dependencies :game_die:" - "docker :whale:" + groups: + docker-all: + applies-to: "version-updates" + patterns: + - "*" - package-ecosystem: "github-actions" directory: "/" @@ -24,6 +29,11 @@ updates: - "bot :robot:" - "dependencies :game_die:" - "github-actions :octocat:" + groups: + github-actions-all: + applies-to: "version-updates" + patterns: + - "*" - package-ecosystem: "npm" directory: "/" @@ -33,6 +43,11 @@ updates: - "bot :robot:" - "dependencies :game_die:" - "javascript :coffee:" + groups: + npm-all: + applies-to: "version-updates" + patterns: + - "*" - package-ecosystem: "pip" directory: "/" @@ -42,3 +57,8 @@ updates: - "bot :robot:" - "dependencies :game_die:" - "python :snake:" + groups: + pip-all: + applies-to: "version-updates" + patterns: + - "*" diff --git a/.github/workflows/_config.yml b/.github/workflows/_config.yml index e7493ce17..728aa1ca4 100644 --- a/.github/workflows/_config.yml +++ b/.github/workflows/_config.yml @@ -7,7 +7,7 @@ on: inputs: platforms: description: "The platforms to build (CSV)" - default: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le + default: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x required: false type: string outputs: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d065ff506..4e3d8b173 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,7 +43,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # tag=v2.7.0 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # tag=v2.10.1 with: egress-policy: block @@ -65,7 +65,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # tag=v2.7.0 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # tag=v2.10.1 with: egress-policy: block @@ -87,7 +87,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # tag=v2.7.0 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # tag=v2.10.1 with: egress-policy: block @@ -132,18 +132,18 @@ jobs: uses: felddy/reusable-workflows/.github/workflows/docker-build-image.yml@v2 with: artifact_name: pre-installed-${{ needs.config.outputs.image_artifact_name_stem }}-${{ needs.config.outputs.test_platform }} - build_arg_1_name: FOUNDRY_PASSWORD - build_arg_2_name: FOUNDRY_USERNAME - build_arg_3_name: VERSION + build_arg_1_name: VERSION + build_secret_1_name: foundry_password + build_secret_2_name: foundry_username cache_from_scopes: ${{ needs.config.outputs.test_platform }}-pre-installed cache_to_scope: ${{ needs.config.outputs.test_platform }}-pre-installed image_archive_name_stem: ${{ needs.config.outputs.test_platform }} image_labels: ${{ needs.metadata.outputs.image_labels }} platforms: ${{ needs.config.outputs.test_platform }} secrets: - build_arg_1_value: ${{ secrets.FOUNDRY_PASSWORD }} - build_arg_2_value: ${{ secrets.FOUNDRY_USERNAME }} - build_arg_3_value: ${{ needs.metadata.outputs.source_version }} + build_arg_1_value: ${{ needs.metadata.outputs.source_version }} + build_secret_1_value: ${{ secrets.FOUNDRY_PASSWORD }} + build_secret_2_value: ${{ secrets.FOUNDRY_USERNAME }} image_archive_key: ${{ secrets.ARTIFACT_KEY }} # Since we need to pass the foundryvtt.com credentials to the tests, we can't diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 5947a5d65..982a85655 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -44,17 +44,17 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # tag=v2.7.0 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # tag=v2.10.1 with: # TODO: change to 'egress-policy: block' after couple of runs egress-policy: audit - name: Checkout repository - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # tag=v4.1.4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@cdcdbb579706841c47f7063dda365e292e5cad7a # tag=codeql-bundle-v2.13.4 + uses: github/codeql-action/init@662472033e021d55d94146f66f6058822b0b39fd # tag=codeql-bundle-v3.27.0 with: languages: ${{ matrix.language }} @@ -62,7 +62,7 @@ jobs: # Java). If this step fails, then you should remove it and run the build # manually (see below). - name: Autobuild - uses: github/codeql-action/autobuild@cdcdbb579706841c47f7063dda365e292e5cad7a # tag=codeql-bundle-v2.13.4 + uses: github/codeql-action/autobuild@662472033e021d55d94146f66f6058822b0b39fd # tag=codeql-bundle-v3.27.0 # ℹī¸ Command-line programs to run using the OS shell. 📚 # https://git.io/JvXDl @@ -76,4 +76,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@cdcdbb579706841c47f7063dda365e292e5cad7a # tag=codeql-bundle-v2.13.4 + uses: github/codeql-action/analyze@662472033e021d55d94146f66f6058822b0b39fd # tag=codeql-bundle-v3.27.0 diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 22f956f35..1587b9454 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -12,10 +12,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # tag=v2.7.0 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # tag=v2.10.1 with: # TODO: change to 'egress-policy: block' after couple of runs egress-policy: audit - name: 'Checkout Repository' - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # tag=v4.1.4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - name: 'Dependency Review' - uses: actions/dependency-review-action@5bbc3ba658137598168acb2ab73b21c432dd411b # tag=v4.2.5 + uses: actions/dependency-review-action@4081bf99e2866ebe428fc0477b69eb4fcda7220a # tag=v4.4.0 diff --git a/.github/workflows/docker-pytest-image.yml b/.github/workflows/docker-pytest-image.yml index e5287767f..4a9474a3a 100644 --- a/.github/workflows/docker-pytest-image.yml +++ b/.github/workflows/docker-pytest-image.yml @@ -73,7 +73,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # tag=v2.7.0 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # tag=v2.10.1 with: egress-policy: audit # allowed-endpoints: > @@ -108,14 +108,14 @@ jobs: echo "do_decryption=false" >> $GITHUB_OUTPUT fi - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # tag=v4.1.4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - id: setup-python - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # tag=v5.1.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # tag=v5.3.0 with: python-version: ${{ inputs.python_version }} - name: Cache testing environments - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # tag=v4.0.2 + uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # tag=v4.1.2 env: BASE_CACHE_KEY: "${{ github.job }}-${{ runner.os }}-\ py${{ steps.setup-python.outputs.python-version }}-" @@ -133,7 +133,7 @@ jobs: pip install --upgrade --requirement requirements-test.txt - name: Download Docker image artifact - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # tag=v4.1.7 + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # tag=v4.1.8 with: name: ${{ inputs.image_artifact_name }} path: ${{ env.ARTIFACT_WORK_DIR }} @@ -183,7 +183,7 @@ jobs: - name: Upload unencrypted data artifacts if: ( success() || failure() ) && steps.check_data_archive_key.outputs.do_encryption == 'false' - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # tag=v4.3.3 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # tag=v4.4.3 with: name: ${{ inputs.data_artifact_name }} path: data.tar.gz @@ -191,7 +191,7 @@ jobs: - name: Upload encrypted data artifacts if: ( success() || failure() ) && steps.check_data_archive_key.outputs.do_encryption == 'true' - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # tag=v4.3.3 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # tag=v4.4.3 with: name: ${{ inputs.data_artifact_name }} path: data.tar.7z diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 9ac45c999..29402f0be 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -28,12 +28,12 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # tag=v4.1.4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # tag=v2.3.1 + uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # tag=v2.4.0 with: results_file: results.sarif results_format: sarif @@ -52,7 +52,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # tag=v4.3.3 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # tag=v4.4.3 with: name: SARIF file path: results.sarif @@ -60,6 +60,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@cdcdbb579706841c47f7063dda365e292e5cad7a # tag=codeql-bundle-v2.13.4 + uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # tag=codeql-bundle-v3.27.0 with: sarif_file: results.sarif diff --git a/.github/workflows/stale-issues.yml b/.github/workflows/stale-issues.yml index 5998c2b8d..0170f2dc4 100644 --- a/.github/workflows/stale-issues.yml +++ b/.github/workflows/stale-issues.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # tag=v2.7.0 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # tag=v2.10.1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml index 8a316400e..f796b3da5 100644 --- a/.github/workflows/sync-labels.yml +++ b/.github/workflows/sync-labels.yml @@ -20,13 +20,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # tag=v2.7.0 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # tag=v2.10.1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # tag=v4.1.4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - name: Sync repository labels if: success() - uses: crazy-max/ghaction-github-labeler@de749cf181958193cb7debf1a9c5bb28922f3e1b # tag=v5.0.0 + uses: crazy-max/ghaction-github-labeler@b54af0c25861143e7c8813d7cbbf46d2c341680c # tag=v5.1.0 with: # This is a hideous ternary equivalent so we only do a dry run unless # this workflow is triggered by the develop branch. diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5828261c4..ea23554bf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ default_language_version: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.6.0 hooks: - id: check-case-conflict - id: check-executables-have-shebangs @@ -32,17 +32,24 @@ repos: # Text file hooks - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.33.0 + rev: v0.41.0 hooks: - id: markdownlint args: - --config=.mdl_config.yaml - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.0-alpha.4 + # This is the last version of v3 available from the mirror. We should hold + # here until v4, which is currently in alpha, is more stable. + rev: v3.1.0 hooks: - id: prettier + # This is the latest version of v3 available from NPM. The pre-commit + # mirror does not pull tags for old major versions once a new major + # version tag is published. + additional_dependencies: + - prettier@3.3.1 - repo: https://github.com/adrienverge/yamllint - rev: v1.29.0 + rev: v1.35.1 hooks: - id: yamllint args: @@ -50,42 +57,75 @@ repos: # GitHub Actions hooks - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.21.0 + rev: 0.28.4 hooks: - id: check-github-actions - id: check-github-workflows # pre-commit hooks - repo: https://github.com/pre-commit/pre-commit - rev: v3.0.4 + rev: v3.7.1 hooks: - id: validate_manifest + # Go hooks + - repo: https://github.com/TekWizely/pre-commit-golang + rev: v1.0.0-rc.1 + hooks: + # Style Checkers + - id: go-critic + # StaticCheck + - id: go-staticcheck-repo-mod + # Go Build + - id: go-build-repo-mod + # Go Mod Tidy + - id: go-mod-tidy-repo + # Go Test + - id: go-test-repo-mod + # Go Vet + - id: go-vet-repo-mod + # GoSec + - id: go-sec-repo-mod + # goimports + - id: go-imports-repo + args: + # Write changes to files + - -w + # Nix hooks + - repo: https://github.com/nix-community/nixpkgs-fmt + rev: v1.3.0 + hooks: + - id: nixpkgs-fmt + # Shell script hooks - - repo: https://github.com/cisagov/pre-commit-shfmt - rev: v0.0.2 + - repo: https://github.com/scop/pre-commit-shfmt + rev: v3.8.0-1 hooks: - id: shfmt args: + # List files that will be formatted + - --list + # Write result to file instead of stdout + - --write # Indent by two spaces - - -i - - '2' + - --indent + - "2" # Binary operators may start a line - - -bn + - --binary-next-line # Switch cases are indented - - -ci + - --case-indent # Redirect operators are followed by a space - - -sr - - repo: https://github.com/detailyang/pre-commit-shell - rev: 1.0.5 + - --space-redirects + - repo: https://github.com/shellcheck-py/shellcheck-py + rev: v0.10.0.1 hooks: - - id: shell-lint + - id: shellcheck args: [-x] # Python hooks # Run bandit on the "tests" tree with a configuration - repo: https://github.com/PyCQA/bandit - rev: 1.7.4 + rev: 1.7.8 hooks: - id: bandit name: bandit (tests tree) @@ -94,50 +134,77 @@ repos: - --config=.bandit.yml # Run bandit on everything except the "tests" tree - repo: https://github.com/PyCQA/bandit - rev: 1.7.4 + rev: 1.7.8 hooks: - id: bandit name: bandit (everything else) exclude: tests - - repo: https://github.com/psf/black - rev: 23.1.0 + - repo: https://github.com/psf/black-pre-commit-mirror + rev: 24.4.2 hooks: - id: black - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 7.0.0 hooks: - id: flake8 additional_dependencies: - flake8-docstrings - repo: https://github.com/PyCQA/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.0.1 + rev: v1.10.0 hooks: - id: mypy + additional_dependencies: + - types-setuptools - repo: https://github.com/asottile/pyupgrade - rev: v3.3.1 + rev: v3.15.2 hooks: - id: pyupgrade # Ansible hooks - - repo: https://github.com/ansible-community/ansible-lint - rev: v6.14.0a0 + - repo: https://github.com/ansible/ansible-lint + rev: v24.6.0 hooks: - id: ansible-lint - # files: molecule/default/playbook.yml + additional_dependencies: + # On its own ansible-lint does not pull in ansible, only + # ansible-core. Therefore, if an Ansible module lives in + # ansible instead of ansible-core, the linter will complain + # that the module is unknown. In these cases it is + # necessary to add the ansible package itself as an + # additional dependency, with the same pinning as is done in + # requirements-test.txt of cisagov/skeleton-ansible-role. + # - ansible>=9,<10 + # ansible-core 2.16.3 through 2.16.6 suffer from the bug + # discussed in ansible/ansible#82702, which breaks any + # symlinked files in vars, tasks, etc. for any Ansible role + # installed via ansible-galaxy. Hence we never want to + # install those versions. + # + # Note that any changes made to this dependency must also be + # made in requirements.txt in cisagov/skeleton-packer and + # requirements-test.txt in cisagov/skeleton-ansible-role. + - ansible-core>=2.16.7 # Terraform hooks - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.77.1 + rev: v1.90.0 hooks: - id: terraform_fmt - id: terraform_validate # Docker hooks - repo: https://github.com/IamTheFij/docker-pre-commit - rev: v2.1.1 + rev: v3.0.1 hooks: - id: docker-compose-check + + # Packer hooks + - repo: https://github.com/cisagov/pre-commit-packer + rev: v0.0.2 + hooks: + - id: packer_validate + - id: packer_fmt diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 318201b18..31bd69c8a 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -55,11 +55,11 @@ further defined and clarified by project maintainers. ## Enforcement ## Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at abuse@geekpad.com. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. +reported by contacting the project team at . All complaints +will be reviewed and investigated and will result in a response that is deemed +necessary and appropriate to the circumstances. The project team is obligated to +maintain confidentiality with regard to the reporter of an incident. Further +details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other diff --git a/Dockerfile b/Dockerfile index 765f80a2a..4d9e54d32 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,9 @@ -ARG FOUNDRY_PASSWORD ARG FOUNDRY_RELEASE_URL -ARG FOUNDRY_USERNAME -ARG FOUNDRY_VERSION=12.320 -ARG NODE_IMAGE_VERSION=18-alpine3.18 +ARG FOUNDRY_VERSION=13.332 +ARG NODE_IMAGE_VERSION=20-bookworm-slim ARG VERSION -FROM node:${NODE_IMAGE_VERSION} as compile-typescript-stage +FROM node:${NODE_IMAGE_VERSION} AS compile-typescript-stage WORKDIR /root @@ -19,11 +17,13 @@ COPY /src/*.ts src/ RUN tsc RUN grep -l "#!" dist/*.js | xargs chmod a+x -FROM node:${NODE_IMAGE_VERSION} as optional-release-stage +FROM node:${NODE_IMAGE_VERSION} AS optional-release-stage + +# This stage is optional and will only be executed if the FOUNDRY_RELEASE_URL or +# FOUNDRY_USERNAME and FOUNDRY_PASSWORD secrets are provided. It will download +# and extract the Foundry VTT release for inclusion in the final stage. -ARG FOUNDRY_PASSWORD ARG FOUNDRY_RELEASE_URL -ARG FOUNDRY_USERNAME ARG FOUNDRY_VERSION ENV ARCHIVE="foundryvtt-${FOUNDRY_VERSION}.zip" @@ -37,19 +37,29 @@ COPY --from=compile-typescript-stage \ ./ # .placeholder file to mitigate https://github.com/moby/moby/issues/37965 RUN mkdir dist && touch dist/.placeholder + RUN \ - if [ -n "${FOUNDRY_USERNAME}" ] && [ -n "${FOUNDRY_PASSWORD}" ]; then \ + --mount=type=secret,id=foundry_username,required=false \ + --mount=type=secret,id=foundry_password,required=false \ + echo ">>> username: $(cat /run/secrets/foundry_username)" && \ + echo ">>> password: $(cat /run/secrets/foundry_password)" && \ npm install && \ - ./authenticate.js "${FOUNDRY_USERNAME}" "${FOUNDRY_PASSWORD}" cookiejar.json && \ - s3_url=$(./get_release_url.js --retry 5 cookiejar.json "${FOUNDRY_VERSION}") && \ - wget -O ${ARCHIVE} "${s3_url}" && \ - unzip -d dist ${ARCHIVE} 'resources/*'; \ + if [ -f /run/secrets/foundry_username ] && [ -f /run/secrets/foundry_password ]; then \ + ./authenticate.js "$(cat /run/secrets/foundry_username)" "$(cat /run/secrets/foundry_password)" cookiejar.json && \ + presigned_url=$(./get_release_url.js --retry 5 cookiejar.json "${FOUNDRY_VERSION}") && \ + DOWNLOAD_URL="${presigned_url}"; \ elif [ -n "${FOUNDRY_RELEASE_URL}" ]; then \ - wget -O ${ARCHIVE} "${FOUNDRY_RELEASE_URL}" && \ + DOWNLOAD_URL="${FOUNDRY_RELEASE_URL}"; \ + else \ + echo "No valid credentials or pre-signed URL provided. Skipping pre-installation."; \ + fi && \ + if [ -n "${DOWNLOAD_URL}" ]; then \ + apt-get update && apt-get install -y unzip wget && \ + wget -O ${ARCHIVE} "${DOWNLOAD_URL}" && \ unzip -d dist ${ARCHIVE} 'resources/*'; \ fi -FROM node:${NODE_IMAGE_VERSION} as final-stage +FROM node:${NODE_IMAGE_VERSION} AS final-stage ARG FOUNDRY_UID=421 ARG FOUNDRY_VERSION @@ -77,13 +87,15 @@ COPY \ ./ RUN addgroup --system --gid ${FOUNDRY_UID} foundry \ && adduser --system --uid ${FOUNDRY_UID} --ingroup foundry foundry \ - && apk --update --no-cache add \ + && apt-get update && apt-get install -y \ curl \ file \ + gosu \ jq \ sed \ - su-exec \ tzdata \ + unzip \ + && rm -rf /var/lib/apt/lists/* \ && npm install && echo ${VERSION} > image_version.txt VOLUME ["/data"] diff --git a/README.md b/README.md index 3280be6e9..33936d2ba 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@
- +Docker whale logo carrying the FoundryVTT icosahedron logo while floating
+  in water.
# foundryvtt-docker # @@ -8,11 +11,11 @@ [![CodeQL](https://github.com/felddy/foundryvtt-docker/workflows/CodeQL/badge.svg)](https://github.com/felddy/foundryvtt-docker/actions/workflows/codeql-analysis.yml) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/felddy/foundryvtt-docker/badge)](https://securityscorecards.dev/viewer/?uri=github.com/felddy/foundryvtt-docker) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5966/badge)](https://bestpractices.coreinfrastructure.org/projects/5966) -[![FoundryVTT Release Version: v12.320](https://img.shields.io/badge/release-v12.320-brightgreen?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAIRlWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABIAAAAAQAAAEgAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAAA6gAwAEAAAAAQAAAA4AAAAATspU+QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KTMInWQAAAiFJREFUKBVVks1rE1EUxc+d5tO0prZVSZsUhSBIPyC02ooWurJ0I7rQlRvdC/4N4h9gt7pyoRTswpWgILgQBIOIiC340VhbpC0Ek85MGmPmXc+baWpNGJg77/7uOffeB+z9FHB0FrH9eLwwqpOF0f34KrpsTicW+6L8KE8QhO/n8n1IOgtQHYZA+a/Ai9+Wd6v1g7liq5A2OjKSQNa9hkO4hAzOIylf6CHALk6hoWXsylPkfjyyApaJhVCxmERy5zLSuI7D8h1H5BWht1aBhS6wdI3pN7GabyuyS4JPrchzujmNjDxAVrrRL2PoxRSGxOfjssgEjkkJvVJBWu6h5M7YenvDoOO0OgicD4TPIKWbBG6xvwTaKCMwSU7hKxK6gt8mbsFIMaF5iDyjUg6iPnqc58higCr9fD4iTvWMziAmK2g73f/AADVWX0YXrlChirgOcqL3WXYBYpTfUuxzjkW30dI1C0ZW1RnjMopo4C56MIs6CgQrMER2cJoz9zjdO2iz17g2yZUjqzHWbuA4/ugiEz7DVRe/aLxmcvDQ5Cq+oWGWeDbAgiETXgArrVOFGzR0EkclxrVMcpfLgFThY5roe2yz95ZZkzcbj22+w2VG8Pz6Q/b5Gr6uM9mw04uo6ll4tOlhE8a8xNzGYihCJoT+u3I4kUIp6OM0X9CHHds8frbqsrXlh9CB62nj8L5a9Y4DHR/K68TgcHhoz607Qp34L72X0rdSdM+vAAAAAElFTkSuQmCC)](https://foundryvtt.com/releases/12.320) +[![FoundryVTT Release Version: v13.332](https://img.shields.io/badge/release-v13.332-brightgreen?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAIRlWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABIAAAAAQAAAEgAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAAA6gAwAEAAAAAQAAAA4AAAAATspU+QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KTMInWQAAAiFJREFUKBVVks1rE1EUxc+d5tO0prZVSZsUhSBIPyC02ooWurJ0I7rQlRvdC/4N4h9gt7pyoRTswpWgILgQBIOIiC340VhbpC0Ek85MGmPmXc+baWpNGJg77/7uOffeB+z9FHB0FrH9eLwwqpOF0f34KrpsTicW+6L8KE8QhO/n8n1IOgtQHYZA+a/Ai9+Wd6v1g7liq5A2OjKSQNa9hkO4hAzOIylf6CHALk6hoWXsylPkfjyyApaJhVCxmERy5zLSuI7D8h1H5BWht1aBhS6wdI3pN7GabyuyS4JPrchzujmNjDxAVrrRL2PoxRSGxOfjssgEjkkJvVJBWu6h5M7YenvDoOO0OgicD4TPIKWbBG6xvwTaKCMwSU7hKxK6gt8mbsFIMaF5iDyjUg6iPnqc58higCr9fD4iTvWMziAmK2g73f/AADVWX0YXrlChirgOcqL3WXYBYpTfUuxzjkW30dI1C0ZW1RnjMopo4C56MIs6CgQrMER2cJoz9zjdO2iz17g2yZUjqzHWbuA4/ugiEz7DVRe/aLxmcvDQ5Cq+oWGWeDbAgiETXgArrVOFGzR0EkclxrVMcpfLgFThY5roe2yz95ZZkzcbj22+w2VG8Pz6Q/b5Gr6uM9mw04uo6ll4tOlhE8a8xNzGYihCJoT+u3I4kUIp6OM0X9CHHds8frbqsrXlh9CB62nj8L5a9Y4DHR/K68TgcHhoz607Qp34L72X0rdSdM+vAAAAAElFTkSuQmCC)](https://foundryvtt.com/releases/13.332) [![Docker Pulls](https://img.shields.io/docker/pulls/felddy/foundryvtt)](https://hub.docker.com/r/felddy/foundryvtt) [![Docker Image Size (latest by date)](https://img.shields.io/docker/image-size/felddy/foundryvtt)](https://hub.docker.com/r/felddy/foundryvtt) -[![Platforms](https://img.shields.io/badge/platforms-amd64%20%7C%20arm%2Fv6%20%7C%20arm%2Fv7%20%7C%20arm64%20%7C%20ppc64le-blue)](https://hub.docker.com/r/felddy/foundryvtt/tags) +[![Platforms](https://img.shields.io/badge/platforms-amd64%20%7C%20arm%2Fv7%20%7C%20arm64%20%7C%20ppc64le%20%7C%20s390x-blue)](https://hub.docker.com/r/felddy/foundryvtt/tags) You can get a [Foundry Virtual Tabletop](https://foundryvtt.com) instance up and running in minutes using this container. This Docker container is designed to @@ -43,7 +46,7 @@ docker run \ felddy/foundryvtt:release ``` -> [!NOTE] +> [!TIP] > If you are using `bash`, or a similar shell, consider pre-pending the Docker > command with a space to prevent your credentials from being committed to the > shell history list. See: @@ -212,9 +215,9 @@ It is recommended that most users use the `:release` tag. | Image:tag | Description | |-----------|-------------| |`felddy/foundryvtt:release` | The most recent image from the `stable` channel. These images are **considered stable**, and well-tested. Most users will use this tag. The `latest` tag always points to the same version as `release`.| -|`felddy/foundryvtt:12.320.0`| An exact image version. | -|`felddy/foundryvtt:12.320`| The most recent image matching the major and minor version numbers. | -|`felddy/foundryvtt:12`| The most recent image matching the major version number. | +|`felddy/foundryvtt:13.332.0`| An exact image version. | +|`felddy/foundryvtt:13.332`| The most recent image matching the major and minor version numbers. | +|`felddy/foundryvtt:13`| The most recent image matching the major version number. | |`felddy/foundryvtt:latest`| See the `release` tag. [Why does `latest` == `release`?](https://vsupalov.com/docker-latest-tag/) | See the [tags tab](https://hub.docker.com/r/felddy/foundryvtt/tags) on Docker @@ -257,23 +260,23 @@ evaluated in the following order of precedence: ***Note:*** `FOUNDRY_USERNAME` and `FOUNDRY_PASSWORD` may be set [using secrets](#using-secrets) instead of environment variables. -#### Pre-signed URL variable #### +#### Presigned URL variable #### | Name | Purpose | |------------------|----------| -| `FOUNDRY_RELEASE_URL` | S3 pre-signed URL generate from the user's profile. Required for downloading an application distribution. | +| `FOUNDRY_RELEASE_URL` | The presigned URL generate from the user's profile. Required for downloading an application distribution. | ### Optional variables ### | Name | Purpose | Default | |-------|---------|---------| -| `CONTAINER_CACHE` | Set a path to cache downloads of the Foundry distribution archive and speed up subsequent container startups. The path should be in `/data` or another persistent mount point in the container. Set to `""` to disable. ***Note***: When the cache is disabled the container may sleep instead of exiting, in certain circumstances, to prevent a download loop. A distribution can be pre-downloaded and placed into a cache directory. The distribution's name must be of the form: `foundryvtt-12.320.zip`| `/data/container_cache` | +| `CONTAINER_CACHE` | Set a path to cache downloads of the Foundry distribution archive and speed up subsequent container startups. The path should be in `/data` or another persistent mount point in the container. Set to `""` to disable. ***Note***: When the cache is disabled the container may sleep instead of exiting, in certain circumstances, to prevent a download loop. A distribution can be pre-downloaded and placed into a cache directory. The distribution's name must be of the form: `foundryvtt-13.332.zip`| `/data/container_cache` | | `CONTAINER_CACHE_SIZE` | Set the maximum number of distribution versions to keep in the cache. The minimum is `1`. When the limit is exceeded, the oldest versions (lowest version numbers) are removed first. Unset to disable cache size management and keep all versions. | | | `CONTAINER_PATCHES` | Set a path to a directory of shell scripts to be sourced after Foundry is installed but before it is started. The path should be in `/data` or another persistent mount point in the container. e.g.; `/data/container_patches` Patch files are sourced in lexicographic order. `CONTAINER_PATCHES` are processed after `CONTAINER_PATCH_URLS`.| | | `CONTAINER_PATCH_URLS` | Set to a space-delimited list of URLs to be sourced after Foundry is installed but before it is started. Patch URLs are sourced in the order specified. `CONTAINER_PATCH_URLS` are processed before `CONTAINER_PATCHES`. ⚠ī¸ **Only use patch URLs from trusted sources!** | | | `CONTAINER_PRESERVE_CONFIG` | Normally new `options.json` and `admin.txt` files are generated by the container at each startup. Setting this to `true` prevents the container from modifying these files when they exist. If they do not exist, they will be created as normal. | `false` | | `CONTAINER_PRESERVE_OWNER` | Normally the ownership of the `/data` directory and its contents are changed to match that of the server at startup. Setting this to a regular expression will exclude any matching paths and preserve their ownership. *Note: This is a match on the whole path, not a search.* This is useful if you want mount a volume as read-only inside `/data` (e.g.; a volume that contains assets mounted at `/data/Data/assets`). | | -| `CONTAINER_URL_FETCH_RETRY` | Number of times to retry fetching the S3 pre-signed URL using exponential back off. This behavior is useful in continuous integration environments where multiple parallel workflows can exceed the rate-limit of the URL generation service. | `0` | +| `CONTAINER_URL_FETCH_RETRY` | Number of times to retry fetching the presigned URL using exponential back off. This behavior is useful in continuous integration environments where multiple parallel workflows can exceed the rate-limit of the URL generation service. | `0` | | `CONTAINER_VERBOSE` | Set to `true` to enable verbose logging for the container utility scripts. | `false` | | `FOUNDRY_ADMIN_KEY` | Admin password to be applied at startup. If omitted the admin password will be cleared. May be set [using secrets](#using-secrets). | | | `FOUNDRY_AWS_CONFIG` | An absolute or relative path that points to the [awsConfig.json](https://foundryvtt.com/article/aws-s3/) or `true` for AWS environment variable [credentials evaluation](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html) usage. | `null` | @@ -299,7 +302,7 @@ secrets](#using-secrets) instead of environment variables. | `FOUNDRY_UID` | `uid` the daemon will be run under. | `foundry` | | `FOUNDRY_UPNP` | Allow Universal Plug and Play to automatically request port forwarding for the Foundry server port to your local network address. | `false` | | `FOUNDRY_UPNP_LEASE_DURATION` | Sets the Universal Plug and Play lease duration, allowing for the possibility of permanent leases for routers which do not support temporary leases. To define an indefinite lease duration set the value to `0`. | `null` | -| `FOUNDRY_VERSION` | Version of Foundry Virtual Tabletop to install. | `12.320` | +| `FOUNDRY_VERSION` | Version of Foundry Virtual Tabletop to install. | `13.332` | | `FOUNDRY_WORLD` | The world to startup at system start. | `null` | | `TIMEZONE` | Container [TZ database name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List) | `UTC` | @@ -334,8 +337,8 @@ Build the image locally using this git repository as the [build context](https:/ ```console docker build \ - --build-arg VERSION=12.320.0 \ - --tag felddy/foundryvtt:12.320.0 \ + --build-arg VERSION=13.332.0 \ + --tag felddy/foundryvtt:13.332.0 \ https://github.com/felddy/foundryvtt-docker.git#develop ``` @@ -358,9 +361,9 @@ Docker: ```console docker buildx build \ --platform linux/amd64 \ - --build-arg VERSION=12.320.0 \ + --build-arg VERSION=13.332.0 \ --output type=docker \ - --tag felddy/foundryvtt:12.320.0 . + --tag felddy/foundryvtt:13.332.0 . ``` ## Pre-installed distribution builds ## @@ -369,27 +372,47 @@ It is possible to install a Foundry Virtual Tabletop distribution into the Docker image at build-time. This results in a significantly larger Docker image, but removes the need to install a distribution at container startup, resulting in a faster startup. It also moves the user authentication to -build-time instead of start-time. **Note**: Credentials are only used to fetch -a distribution, and are not stored in the resulting image. +build-time instead of start-time. + +### Image build with credentials ### -Build the image with credentials: +> [!NOTE] +> Credentials are only used to fetch a distribution, and are not stored +> in the resulting image. ```console docker build \ - --build-arg FOUNDRY_USERNAME='' \ - --build-arg FOUNDRY_PASSWORD='' \ - --build-arg VERSION=12.320.0 \ - --tag felddy/foundryvtt:12.320.0 \ + --secret id=foundry_username,src=<(echo "") \ + --secret id=foundry_password,src=<(echo "") \ + --build-arg VERSION=13.332.0 \ + --tag felddy/foundryvtt:13.332.0 \ https://github.com/felddy/foundryvtt-docker.git#develop ``` -Or build the image using a temporary URL: +> [!TIP] +> If you have stored your credentials in a json file, as documented in the +> [using secrets](#using-secrets) section above, you can extract the username +> and password and pass them as build secrets using the following syntax: +> +> ```console +> docker build \ +> --secret id=foundry_username,src=<(jq -r '.foundry_username' path/to/credentials.json) \ +> --secret id=foundry_password,src=<(jq -r '.foundry_password' path/to/credentials.json) \ +> --build-arg VERSION=13.332.0 \ +> --tag felddy/foundryvtt:13.332.0 \ +> https://github.com/felddy/foundryvtt-docker.git#develop +> ``` + +More information about Docker build secrets can be found in the [Docker +documentation](https://docs.docker.com/build/building/secrets/). + +### Image build with a temporary URL ### ```console docker build \ --build-arg FOUNDRY_RELEASE_URL='' \ - --build-arg VERSION=12.320.0 \ - --tag felddy/foundryvtt:12.320.0 \ + --build-arg VERSION=13.332.0 \ + --tag felddy/foundryvtt:13.332.0 \ https://github.com/felddy/foundryvtt-docker.git#develop ``` diff --git a/docker-compose.yml b/docker-compose.yml index a2822bb68..0706dd9da 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -51,7 +51,7 @@ services: # - FOUNDRY_UID=foundry # - FOUNDRY_UPNP=false # - FOUNDRY_UPNP_LEASE_DURATION= - # - FOUNDRY_VERSION=12.320 + # - FOUNDRY_VERSION=13.332 # - FOUNDRY_WORLD= # - TIMEZONE=US/Eastern ports: diff --git a/package-lock.json b/package-lock.json index 7461e4a68..fa7815734 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,19 +9,19 @@ "version": "2.0.0", "license": "MIT", "dependencies": { - "cheerio": "^1.0.0-rc.12", + "cheerio": "^1.0.0", "docopt": "^0.6.2", "fetch-cookie": "^3.0.1", "node-fetch": "^3.3.2", "tough-cookie-file-store": "^2.0.3", - "winston": "^3.13.0" + "winston": "^3.16.0" }, "devDependencies": { "@types/cheerio": "^0.22.35", "@types/docopt": "^0.6.37", "@types/tough-cookie": "^4.0.5", "@types/tough-cookie-file-store": "^2.0.4", - "typescript": "^5.4.5" + "typescript": "^5.6.3" } }, "node_modules/@colors/colors": { @@ -94,20 +94,25 @@ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", + "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", + "license": "MIT", "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" + "domutils": "^3.1.0", + "encoding-sniffer": "^0.2.0", + "htmlparser2": "^9.1.0", + "parse5": "^7.1.2", + "parse5-htmlparser2-tree-adapter": "^7.0.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^6.19.5", + "whatwg-mimetype": "^4.0.0" }, "engines": { - "node": ">= 6" + "node": ">=18.17" }, "funding": { "url": "https://github.com/cheeriojs/cheerio?sponsor=1" @@ -250,13 +255,14 @@ } }, "node_modules/domutils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", - "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", - "domhandler": "^5.0.1" + "domhandler": "^5.0.3" }, "funding": { "url": "https://github.com/fb55/domutils?sponsor=1" @@ -267,10 +273,24 @@ "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" }, + "node_modules/encoding-sniffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", + "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, "node_modules/entities": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.1.tgz", - "integrity": "sha512-o4q/dYJlmyjP2zfnaWDUC6A3BQFmVTX+tZPezK7k0GLSU9QYCauscf5Y+qcEPzKL+EixVouYDgLQK5H9GrLpkg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -331,9 +351,9 @@ } }, "node_modules/htmlparser2": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", - "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -341,11 +361,24 @@ "url": "https://github.com/sponsors/fb55" } ], + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "entities": "^4.3.0" + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, "node_modules/inherits": { @@ -450,11 +483,12 @@ } }, "node_modules/parse5": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz", - "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "license": "MIT", "dependencies": { - "entities": "^4.3.0" + "entities": "^4.4.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" @@ -472,6 +506,18 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -535,6 +581,12 @@ "node": ">=10" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, "node_modules/set-cookie-parser": { "version": "2.4.8", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.4.8.tgz", @@ -603,9 +655,9 @@ } }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -615,6 +667,15 @@ "node": ">=14.17" } }, + "node_modules/undici": { + "version": "6.19.7", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.7.tgz", + "integrity": "sha512-HR3W/bMGPSr90i8AAp2C4DM3wChFdJPLrWYpIS++LxS8K+W535qftjt+4MyjNYHeWabMj1nvtmLIi7l++iq91A==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, "node_modules/universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", @@ -645,16 +706,37 @@ "node": ">= 8" } }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/winston": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.13.0.tgz", - "integrity": "sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.16.0.tgz", + "integrity": "sha512-xz7+cyGN5M+4CmmD4Npq1/4T+UZaz7HaeTlAruFUTjk79CNMq+P6H30vlE4z0qfqJ01VHYQwd7OZo03nYm/+lg==", "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", - "logform": "^2.4.0", + "logform": "^2.6.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", @@ -748,17 +830,21 @@ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, "cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", + "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", "requires": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" + "domutils": "^3.1.0", + "encoding-sniffer": "^0.2.0", + "htmlparser2": "^9.1.0", + "parse5": "^7.1.2", + "parse5-htmlparser2-tree-adapter": "^7.0.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^6.19.5", + "whatwg-mimetype": "^4.0.0" } }, "cheerio-select": { @@ -865,13 +951,13 @@ } }, "domutils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", - "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "requires": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", - "domhandler": "^5.0.1" + "domhandler": "^5.0.3" } }, "enabled": { @@ -879,10 +965,19 @@ "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" }, + "encoding-sniffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", + "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", + "requires": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + } + }, "entities": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.1.tgz", - "integrity": "sha512-o4q/dYJlmyjP2zfnaWDUC6A3BQFmVTX+tZPezK7k0GLSU9QYCauscf5Y+qcEPzKL+EixVouYDgLQK5H9GrLpkg==" + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" }, "fecha": { "version": "4.2.3", @@ -921,14 +1016,22 @@ } }, "htmlparser2": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", - "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", "requires": { "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "entities": "^4.3.0" + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "inherits": { @@ -1001,11 +1104,11 @@ } }, "parse5": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz", - "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "requires": { - "entities": "^4.3.0" + "entities": "^4.4.0" } }, "parse5-htmlparser2-tree-adapter": { @@ -1017,6 +1120,14 @@ "parse5": "^7.0.0" } }, + "parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "requires": { + "parse5": "^7.0.0" + } + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -1057,6 +1168,11 @@ "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==" }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "set-cookie-parser": { "version": "2.4.8", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.4.8.tgz", @@ -1113,11 +1229,16 @@ "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==" }, "typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true }, + "undici": { + "version": "6.19.7", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.7.tgz", + "integrity": "sha512-HR3W/bMGPSr90i8AAp2C4DM3wChFdJPLrWYpIS++LxS8K+W535qftjt+4MyjNYHeWabMj1nvtmLIi7l++iq91A==" + }, "universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", @@ -1142,16 +1263,29 @@ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz", "integrity": "sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==" }, + "whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "requires": { + "iconv-lite": "0.6.3" + } + }, + "whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==" + }, "winston": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.13.0.tgz", - "integrity": "sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.16.0.tgz", + "integrity": "sha512-xz7+cyGN5M+4CmmD4Npq1/4T+UZaz7HaeTlAruFUTjk79CNMq+P6H30vlE4z0qfqJ01VHYQwd7OZo03nYm/+lg==", "requires": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", - "logform": "^2.4.0", + "logform": "^2.6.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", diff --git a/package.json b/package.json index e422d5d6f..1737a1442 100644 --- a/package.json +++ b/package.json @@ -4,12 +4,12 @@ "url": "https://github.com/felddy/foundryvtt-docker/issues" }, "dependencies": { - "cheerio": "^1.0.0-rc.12", + "cheerio": "^1.0.0", "docopt": "^0.6.2", "fetch-cookie": "^3.0.1", "node-fetch": "^3.3.2", "tough-cookie-file-store": "^2.0.3", - "winston": "^3.13.0" + "winston": "^3.16.0" }, "description": "Utilities to help boot a FoundryVTT server.", "devDependencies": { @@ -17,7 +17,7 @@ "@types/docopt": "^0.6.37", "@types/tough-cookie": "^4.0.5", "@types/tough-cookie-file-store": "^2.0.4", - "typescript": "^5.4.5" + "typescript": "^5.6.3" }, "homepage": "https://github.com/felddy/foundryvtt-docker#readme", "keywords": [ diff --git a/setup.py b/setup.py index 5ddbfe8b8..54562a5f7 100644 --- a/setup.py +++ b/setup.py @@ -68,17 +68,18 @@ def package_vars(version_file): py_modules=[splitext(basename(path))[0] for path in glob("src/*.py")], install_requires=[ "semver == 3.0.2", - "setuptools == 69.5.1", - "wheel == 0.43.0", + "setuptools == 75.3.0", + "wheel == 0.44.0", ], extras_require={ "test": [ - "coverage == 6.5.0", - "coveralls == 3.3.1", - "docker == 7.0.0", - "pre-commit == 3.7.0", - "pytest == 8.2.0", - "pytest-cov == 5.0.0", + "coverage == 7.6.4", + # TODO: Revert to pinned once https://github.com/TheKevJames/coveralls-python/pull/542 is merged + "coveralls @ git+https://github.com/terop/coveralls-python.git@7fb2b536b04f61bb6a73ae5572a17e723459756d", + "docker == 7.1.0", + "pre-commit == 4.0.1", + "pytest == 8.3.3", + "pytest-cov == 6.0.0", ] }, ) diff --git a/src/_version.py b/src/_version.py index 91926dc87..e32408143 100644 --- a/src/_version.py +++ b/src/_version.py @@ -1,3 +1,3 @@ """This file defines the version of this module.""" -__version__ = "12.320.0" +__version__ = "13.332.0" diff --git a/src/authenticate.ts b/src/authenticate.ts index 687a9bab1..35df2e2db 100755 --- a/src/authenticate.ts +++ b/src/authenticate.ts @@ -24,7 +24,7 @@ Options: // Imports import { CookieJar, Cookie } from "tough-cookie"; import { FileCookieStore } from "tough-cookie-file-store"; -import cheerio from "cheerio"; +import * as cheerio from "cheerio"; import createLogger from "./logging.js"; import winston from "winston"; import docopt from "docopt"; diff --git a/src/check_health.sh b/src/check_health.sh index 6ad5f44d0..f34217f46 100755 --- a/src/check_health.sh +++ b/src/check_health.sh @@ -1,6 +1,4 @@ -#!/bin/sh -# shellcheck disable=SC3010 -# SC3010 - busybox supports [[ ]] +#!/bin/bash if [[ "${FOUNDRY_SSL_CERT:-}" && "${FOUNDRY_SSL_KEY:-}" ]]; then protocol="https" diff --git a/src/entrypoint.sh b/src/entrypoint.sh index 53a8c4921..01b7f4af8 100755 --- a/src/entrypoint.sh +++ b/src/entrypoint.sh @@ -1,13 +1,7 @@ -#!/bin/sh -# shellcheck disable=SC3010,SC3046,SC3051 -# SC3010 - busybox supports [[ ]] -# SC3046 - busybox supports source command -# SC3051 - busybox supports source command +#!/bin/bash set -o nounset set -o errexit -# shellcheck disable=SC3040 -# pipefail is supported by busybox set -o pipefail CONFIG_DIR="/data/Config" @@ -89,9 +83,9 @@ fi # Check to see if an install is required install_required=false -# Track whether an S3 URL request is made. +# Track whether a presigned URL request is made. # We use this information to protect from a download loop. -requested_s3_url=false +requested_presigned_url=false if [ -f "resources/app/package.json" ]; then # FoundryVTT no longer supports the "version" field in package.json # We need to build up a pseudo-version using the generation and build values @@ -113,7 +107,7 @@ if [ $install_required = true ]; then # Determine how we are going to get the release URL if [ "${FOUNDRY_RELEASE_URL:-}" ]; then log "Using FOUNDRY_RELEASE_URL to download release." - s3_url="${FOUNDRY_RELEASE_URL}" + presigned_url="${FOUNDRY_RELEASE_URL}" fi if [[ "${FOUNDRY_USERNAME:-}" && "${FOUNDRY_PASSWORD:-}" ]]; then log "Using FOUNDRY_USERNAME and FOUNDRY_PASSWORD to authenticate." @@ -124,16 +118,16 @@ if [ $install_required = true ]; then ./authenticate.js ${CONTAINER_VERBOSE+--log-level=debug} \ --user-agent="${node_user_agent}" \ "${FOUNDRY_USERNAME}" "${FOUNDRY_PASSWORD}" "${cookiejar_file}" - if [[ ! "${s3_url:-}" ]]; then - # If the s3_url wasn't set by FOUNDRY_RELEASE_URL generate one now. + if [[ ! "${presigned_url:-}" ]]; then + # If the presigned_url wasn't set by FOUNDRY_RELEASE_URL generate one now. log "Using authenticated credentials to download release." # CONTAINER_VERBOSE default value should not be quoted. # shellcheck disable=SC2086 - s3_url=$(./get_release_url.js ${CONTAINER_VERBOSE+--log-level=debug} \ + presigned_url=$(./get_release_url.js ${CONTAINER_VERBOSE+--log-level=debug} \ ${CONTAINER_URL_FETCH_RETRY+--retry=${CONTAINER_URL_FETCH_RETRY}} \ --user-agent="${node_user_agent}" \ "${cookiejar_file}" "${FOUNDRY_VERSION}") - requested_s3_url=true + requested_presigned_url=true fi fi @@ -153,14 +147,14 @@ if [ $install_required = true ]; then release_filename="${CONTAINER_CACHE%%+(/)}${CONTAINER_CACHE:+/}foundryvtt-${FOUNDRY_VERSION}.zip" set -o nounset - if [[ "${s3_url:-}" ]]; then + if [[ "${presigned_url:-}" ]]; then log "Downloading Foundry Virtual Tabletop release." # Download release if newer than cached version. # Filter out warnings about bad date formats if the file is missing. curl ${CONTAINER_VERBOSE+--verbose} --fail --location \ --user-agent "${curl_user_agent}" \ --time-cond "${release_filename}" \ - --output "${downloading_filename}" "${s3_url}" 2>&1 \ + --output "${downloading_filename}" "${presigned_url}" 2>&1 \ | tr "\r" "\n" \ | sed --unbuffered '/^Warning: .* date/d' @@ -204,6 +198,13 @@ if [ $install_required = true ]; then exit 1 fi + # TODO: This is a workaround for a "known issue" with FoundryVTT 13.332 + # Install classic-level module per release notes. + pushd resources/app > /dev/null + log "Installing classic-level module." + npm install classic-level --silent --no-audit --no-fund --no-progress + popd > /dev/null + if [[ "${CONTAINER_CACHE:-}" ]]; then log "Preserving release archive file in cache." # Check if CONTAINER_CACHE_SIZE is set and if so, ensure it's greater than 0 @@ -263,8 +264,11 @@ if [ $install_required = true ]; then log "Using CONTAINER_PATCHES: ${CONTAINER_PATCHES}" if [ -d "${CONTAINER_PATCHES}" ]; then log "Container patches directory detected. Starting patch application..." - for f in "${CONTAINER_PATCHES}"/*; do - [ -f "$f" ] || continue # we can't set nullglob in busybox + shopt -s nullglob # if the directory is empty we want an empty array + patch_files=("${CONTAINER_PATCHES}"/*) + shopt -u nullglob + for f in "${patch_files[@]}"; do + [ -f "$f" ] || continue # skip non-files log "Sourcing patch from file: $f" # shellcheck disable=SC1090 source "$f" @@ -343,7 +347,7 @@ export CONTAINER_PRESERVE_CONFIG FOUNDRY_ADMIN_KEY FOUNDRY_AWS_CONFIG \ FOUNDRY_UPNP_LEASE_DURATION FOUNDRY_WORLD # set the TERM signal handler trap handle_sigterm TERM -su-exec "${FOUNDRY_UID}:${FOUNDRY_GID}" ./launcher.sh "$@" & +gosu "${FOUNDRY_UID}:${FOUNDRY_GID}" ./launcher.sh "$@" & child_pid=$! log_debug "Waiting for child pid: ${child_pid} to exit." wait "$child_pid" @@ -357,9 +361,9 @@ if [ $exit_code -ne 0 ]; then log_error "Child process failed with error code: $exit_code" fi -# If the container requested a new S3 URL but disabled the cache +# If the container requested a new presigned URL but disabled the cache # we are going to sleep forever to prevent a download loop. -if [[ "${requested_s3_url}" == "true" && "${CONTAINER_CACHE:-}" == "" ]]; then +if [[ "${requested_presigned_url}" == "true" && "${CONTAINER_CACHE:-}" == "" ]]; then log_warn "Server exited after downloading a release while the CONTAINER_CACHE was disabled." log_warn "This configuration could lead to a restart loop putting excessive load on the release server." log_warn "Please re-enable the CONTAINER_CACHE to allow the container to safely exit." diff --git a/src/get_license.ts b/src/get_license.ts index b756793be..7bda46b1c 100755 --- a/src/get_license.ts +++ b/src/get_license.ts @@ -32,7 +32,7 @@ Options: // Imports import { CookieJar } from "tough-cookie"; import { FileCookieStore } from "tough-cookie-file-store"; -import cheerio from "cheerio"; +import * as cheerio from "cheerio"; import createLogger from "./logging.js"; import docopt from "docopt"; import fetchCookie from "fetch-cookie"; diff --git a/src/get_release_url.ts b/src/get_release_url.ts index 54334ab5f..23dfa9f9b 100755 --- a/src/get_release_url.ts +++ b/src/get_release_url.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node const doc = ` -Generate a Foundry Virtual Tabletop pre-signed release URL using cookies from +Generate a Foundry Virtual Tabletop presigned release URL using cookies from authenticate.js. The utility will print the release URL to standard out. @@ -77,7 +77,7 @@ async function sleepWithProgress(attempt: number): Promise { } /** - * fetchReleaseURL - Fetch the pre-signed S3 URL. + * fetchReleaseURL - Fetch the presigned URL. * * @param {string} build Build to download. * @param {number} retries Number of retries to attempt. @@ -87,7 +87,7 @@ async function fetchReleaseURL( build: string, retries: number, ): Promise { - logger.info(`Fetching S3 pre-signed release URL for build ${build}...`); + logger.info(`Fetching presigned release URL for build ${build}...`); const release_url: string = `${BASE_URL}/releases/download?build=${build}&platform=linux`; for (var attempt = 1; attempt <= 1 + retries; attempt++) { // If this is not the first attempt, wait a bit before trying again. @@ -109,10 +109,10 @@ async function fetchReleaseURL( continue; } - const s3_url: string | null = response.headers.get("location"); - logger.debug(`S3 presigned URL: ${s3_url}`); + const presigned_url: string | null = response.headers.get("location"); + logger.debug(`Presigned URL: ${presigned_url}`); - return s3_url; + return presigned_url; } throw new Error(`Failed to fetch release URL.`); } @@ -154,7 +154,7 @@ async function main(): Promise { ); } - // Generate an S3 pre-signed URL and print it to stdout. + // Generate a presigned URL and print it to stdout. const releaseURL: string | null = await fetchReleaseURL( foundry_build, retries, diff --git a/src/launcher.sh b/src/launcher.sh index 6854360b5..f09187b30 100755 --- a/src/launcher.sh +++ b/src/launcher.sh @@ -1,15 +1,7 @@ -#!/bin/sh -# shellcheck disable=SC3001,SC3010,SC3021,SC3046,SC3051 -# SC3001 - busybox supports process substitution -# SC3010 - busybox supports [[ ]] -# SC3021 - busybox supports >& -# SC3046 - busybox supports source command -# SC3051 - busybox supports source command +#!/bin/bash set -o nounset set -o errexit -# shellcheck disable=SC3040 -# pipefail is supported by busybox set -o pipefail CONFIG_DIR="/data/Config" @@ -79,4 +71,4 @@ done < <(env -0) log "Starting Foundry Virtual Tabletop." # We want ENV_VAR_CARRY_LIST to word split # shellcheck disable=SC2086 -exec env -i $ENV_VAR_CARRY_LIST node "$@" || log_error "Exec failed with code $?" +exec env -i $ENV_VAR_CARRY_LIST /usr/local/bin/node "$@" || log_error "Exec failed with code $?" diff --git a/src/logging.sh b/src/logging.sh index b25ddf869..b00b73539 100644 --- a/src/logging.sh +++ b/src/logging.sh @@ -1,7 +1,4 @@ -#!/bin/sh -# shellcheck disable=SC3010,SC3037 -# SC3010 - busybox supports [[ ]] -# SC3037 - busybox echo supports flags +#!/bin/bash # Define terminal colors for use in logger functions BLUE="\e[34m" diff --git a/tests/conftest.py b/tests/conftest.py index cec0af534..5918eaea9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -13,7 +13,10 @@ MAIN_SERVICE_NAME = "foundry" REDACTION_REGEXES = [ + # AWS S3 pre-signed URL re.compile(r"AWSAccessKeyId=(.*?)&Signature=(.*?)&"), + # Cloudflare R2 pre-signed URL + re.compile(r"\?verify=([0-9]+-[a-zA-Z0-9%]+)"), ] VERSION_FILE = "src/_version.py" VERSION_SERVICE_NAME = f"{MAIN_SERVICE_NAME}-version"