Skip to content
Open

1.8.4 #224

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 40 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ on:
- main

env:
VERSION_NUMBER: 'v1.8.3'
VERSION_NUMBER: 'v1.8.4'
DOCKERHUB_REGISTRY_NAME: 'digitalghostdev/poke-cli'
AWS_REGION: 'us-west-2'

Expand All @@ -55,7 +55,7 @@ jobs:
args: '-no-fail -fmt sarif -out results.sarif ./...'

- name: Upload SARIF Report
uses: github/codeql-action/upload-sarif@v3
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: results.sarif

Expand All @@ -67,15 +67,19 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_CONFIG: ./gitleaks.toml
GITLEAKS_VERSION: 8.29.0
- name: Run Gitleaks
run: |
docker run --rm -v ${{ github.workspace }}:/path \
ghcr.io/gitleaks/gitleaks:v8.29.0 \
dir /path -c /path/gitleaks.toml --redact -v \
--report-format sarif --report-path /path/gitleaks-results.sarif

- name: Upload SARIF Report
if: always()
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: gitleaks-results.sarif

build-linux-packages:
runs-on: ubuntu-22.04
Expand Down Expand Up @@ -240,16 +244,39 @@ jobs:
if [ "${{ needs.upload-deb-packages.result }}" != "success" ] || \
[ "${{ needs.upload-rpm-packages.result }}" != "success" ] || \
[ "${{ needs.upload-apk-packages.result }}" != "success" ]; then
echo "⚠️ Some uploads failed! ⚠️"
echo "⚠️ Some uploads failed"
exit 1
fi
echo "✅ All packages uploaded successfully! ✅"
echo "✅ All packages uploaded successfully"

build-docs-docker-image:
validate-links:
runs-on: ubuntu-22.04
needs: [gitleaks]
if: needs.gitleaks.result == 'success'

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Check Links
uses: lycheeverse/lychee-action@v2
with:
args: --verbose --config lychee.toml ./docs/**/*.md
fail: false
output: ./lychee-report.md

- name: Upload Report
if: always()
uses: actions/upload-artifact@v4
with:
name: lychee-report
path: ./lychee-report.md

build-docs-docker-image:
runs-on: ubuntu-22.04
needs: [validate-links]
if: needs.validate-links.result == 'success'

steps:
- name: Checkout
uses: actions/checkout@v6
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ poke-cli

# Output of the go coverage tool, specifically when used with LiteIDE
*.out
codecov*

# Dependency directories (remove the comment below to include it)
# vendor/
Expand Down
2 changes: 1 addition & 1 deletion .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ builds:
- windows
- darwin
ldflags:
- -s -w -X main.version=v1.8.3
- -s -w -X main.version=v1.8.4

archives:
- formats: [ 'zip' ]
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ RUN go mod download

COPY . .

RUN go build -ldflags "-X main.version=v1.8.3" -o poke-cli .
RUN go build -ldflags "-X main.version=v1.8.4" -o poke-cli .

# build 2
FROM --platform=$BUILDPLATFORM alpine:3.23
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<img width="425" src="poke-cli.png" alt="pokemon-logo"/>
<h4></h4>
<img src="https://img.shields.io/github/v/release/digitalghost-dev/poke-cli?style=flat-square&logo=git&logoColor=FFCC00&label=Release%20Version&labelColor=EEE&color=FFCC00" alt="version-label">
<img src="https://img.shields.io/docker/image-size/digitalghostdev/poke-cli/v1.8.3?arch=arm64&style=flat-square&logo=docker&logoColor=FFCC00&labelColor=EEE&color=FFCC00" alt="docker-image-size">
<img src="https://img.shields.io/docker/image-size/digitalghostdev/poke-cli/v1.8.4?arch=arm64&style=flat-square&logo=docker&logoColor=FFCC00&labelColor=EEE&color=FFCC00" alt="docker-image-size">
<img src="https://img.shields.io/github/actions/workflow/status/digitalghost-dev/poke-cli/ci.yml?branch=main&style=flat-square&logo=github&logoColor=FFCC00&label=CI&labelColor=EEE&color=FFCC00" alt="ci-status-badge">
</div>
<div align="center">
Expand Down Expand Up @@ -96,11 +96,11 @@ Cloudsmith is a fully cloud-based service that lets you easily create, store, an
3. Choose how to interact with the container:
* Run a single command and exit:
```bash
docker run --rm -it digitalghostdev/poke-cli:v1.8.3 <command> [subcommand] [flag]
docker run --rm -it digitalghostdev/poke-cli:v1.8.4 <command> [subcommand] [flag]
```
* Enter the container and use its shell:
```bash
docker run --rm -it --name poke-cli --entrypoint /bin/sh digitalghostdev/poke-cli:v1.8.3 -c "cd /app && exec sh"
docker run --rm -it --name poke-cli --entrypoint /bin/sh digitalghostdev/poke-cli:v1.8.4 -c "cd /app && exec sh"
# placed into the /app directory, run the program with './poke-cli'
# example: ./poke-cli ability swift-swim
```
Expand Down
2 changes: 1 addition & 1 deletion card_data/pipelines/poke_cli_dbt/dbt_project.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: 'poke_cli_dbt'
version: '1.8.3'
version: '1.8.4'

profile: 'poke_cli_dbt'

Expand Down
168 changes: 168 additions & 0 deletions card_data/pipelines/tests/extract_sets_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent.parent))

import pytest
import polars as pl
import responses
from pipelines.defs.extract.tcgdex.extract_sets import extract_sets_data


@pytest.fixture
def mock_api_response():
"""Sample API responses matching tcgdex series format with sets"""
return {
"https://api.tcgdex.net/v2/en/series/me": {
"id": "me",
"name": "Mega Evolution",
"sets": [
{
"id": "me01",
"name": "Mega Evolution",
"cardCount": {"official": 12, "total": 12},
"logo": "https://example.com/me01.png",
"symbol": "https://example.com/me01-symbol.png",
},
{
"id": "me02",
"name": "Phantasmal Flames",
"cardCount": {"official": 25, "total": 25},
"logo": "https://example.com/me02.png",
"symbol": "https://example.com/me02-symbol.png",
},
],
},
"https://api.tcgdex.net/v2/en/series/sv": {
"id": "sv",
"name": "Scarlet & Violet",
"sets": [
{
"id": "sv01",
"name": "Scarlet & Violet",
"cardCount": {"official": 198, "total": 258},
"logo": "https://example.com/sv01.png",
"symbol": "https://example.com/sv01-symbol.png",
},
{
"id": "sv02",
"name": "Paldea Evolved",
"cardCount": {"official": 193, "total": 279},
"logo": "https://example.com/sv02.png",
"symbol": None,
},
],
},
"https://api.tcgdex.net/v2/en/series/swsh": {
"id": "swsh",
"name": "Sword & Shield",
"sets": [
{
"id": "swsh1",
"name": "Sword & Shield",
"cardCount": {"official": 202, "total": 216},
"logo": None,
"symbol": "https://example.com/swsh1-symbol.png",
},
],
},
}


@pytest.mark.benchmark
@responses.activate
def test_extract_sets_data_success(mock_api_response):
"""Test successful extraction of sets from multiple series"""
# Mock all API calls
for url, response_data in mock_api_response.items():
responses.add(
responses.GET,
url,
json=response_data,
status=200,
)

result = extract_sets_data()

# Assertions
assert isinstance(result, pl.DataFrame) # nosec
assert len(result) == 5 # nosec (2 + 2 + 1 sets)
assert set(result.columns) == { # nosec
"series_id",
"set_id",
"set_name",
"official_card_count",
"total_card_count",
"logo",
"symbol",
}
assert set(result["series_id"].to_list()) == {"me", "sv", "swsh"} # nosec
assert set(result["set_id"].to_list()) == {"me01", "me02", "sv01", "sv02", "swsh1"} # nosec


@pytest.mark.benchmark
@responses.activate
def test_extract_sets_data_empty_sets(mock_api_response):
"""Test extraction when a series has no sets"""
# Modify one response to have empty sets
mock_api_response["https://api.tcgdex.net/v2/en/series/me"]["sets"] = []

for url, response_data in mock_api_response.items():
responses.add(
responses.GET,
url,
json=response_data,
status=200,
)

result = extract_sets_data()

assert isinstance(result, pl.DataFrame) # nosec
assert len(result) == 3 # nosec (0 + 2 + 1 sets)
assert "me" not in result["series_id"].to_list() # nosec


@pytest.mark.benchmark
@responses.activate
def test_extract_sets_data_null_card_counts():
"""Test extraction with null card counts"""
mock_responses = {
"https://api.tcgdex.net/v2/en/series/me": {
"id": "me",
"name": "Mega Evolution",
"sets": [],
},
"https://api.tcgdex.net/v2/en/series/sv": {
"id": "sv",
"name": "Scarlet & Violet",
"sets": [
{
"id": "sv01",
"name": "Scarlet & Violet",
"cardCount": {},
"logo": None,
"symbol": None,
},
],
},
"https://api.tcgdex.net/v2/en/series/swsh": {
"id": "swsh",
"name": "Sword & Shield",
"sets": [],
},
}

for url, response_data in mock_responses.items():
responses.add(
responses.GET,
url,
json=response_data,
status=200,
)

result = extract_sets_data()

assert isinstance(result, pl.DataFrame) # nosec
assert len(result) == 1 # nosec
assert result["official_card_count"].to_list()[0] is None # nosec
assert result["total_card_count"].to_list()[0] is None # nosec
4 changes: 2 additions & 2 deletions card_data/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions cmd/card/cardinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func resizeImage(img image.Image, width, height int) image.Image {

func CardImage(imageURL string) (string, error) {
client := &http.Client{
Timeout: time.Second * 15,
Timeout: time.Second * 60,
}
parsedURL, err := url.Parse(imageURL)
if err != nil || (parsedURL.Scheme != "http" && parsedURL.Scheme != "https") {
Expand All @@ -38,8 +38,14 @@ func CardImage(imageURL string) (string, error) {
return "", fmt.Errorf("non-200 response: %d", resp.StatusCode)
}

// Read body into memory first to avoid timeout during decode
limitedBody := io.LimitReader(resp.Body, 10*1024*1024)
img, _, err := image.Decode(limitedBody)
bodyBytes, err := io.ReadAll(limitedBody)
if err != nil {
return "", fmt.Errorf("failed to read image data: %w", err)
}

img, _, err := image.Decode(bytes.NewReader(bodyBytes))
if err != nil {
return "", fmt.Errorf("failed to decode image: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/card/cardlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func CallCardData(url string) ([]byte, error) {
req.Header.Add("Authorization", "Bearer sb_publishable_oondaaAIQC-wafhEiNgpSQ_reRiEp7j")
req.Header.Add("Content-Type", "application/json")

client := &http.Client{Timeout: 15 * time.Second}
client := &http.Client{Timeout: 60 * time.Second}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("error making GET request: %w", err)
Expand Down
Loading