Skip to content
Merged
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
71 changes: 71 additions & 0 deletions .github/workflows/action-smoke.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: GitHub Action

on:
pull_request:
branches:
- main
paths:
- 'action.yml'
- '.github/workflows/action-smoke.yaml'
- 'tests/data/jsonschema/simple_string.json'
push:
branches:
- main
paths:
- 'action.yml'
- '.github/workflows/action-smoke.yaml'
- 'tests/data/jsonschema/simple_string.json'
workflow_dispatch:

concurrency:
group: action-smoke-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
smoke:
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 1
persist-credentials: false

- name: Prepare smoke fixtures
run: |
set -euo pipefail
mkdir -p "$RUNNER_TEMP/action-smoke/schemas" "$RUNNER_TEMP/action-smoke/generated"
cp tests/data/jsonschema/simple_string.json "$RUNNER_TEMP/action-smoke/schemas/injection\$(touch action-injection-ran).json"

- name: Generate models
uses: ./
with:
input: 'schemas/injection$(touch action-injection-ran).json'
output: generated/model.py
input-file-type: jsonschema
output-model-type: pydantic_v2.BaseModel
check: 'false'
working-directory: ${{ runner.temp }}/action-smoke
extra-args: --disable-timestamp
version: 0.66.3

- name: Check generated models
uses: ./
with:
input: 'schemas/injection$(touch action-injection-ran).json'
output: generated/model.py
input-file-type: jsonschema
output-model-type: pydantic_v2.BaseModel
working-directory: ${{ runner.temp }}/action-smoke
extra-args: --disable-timestamp
version: 0.66.3

- name: Verify shell-sensitive input
run: |
set -euo pipefail
test ! -e "$RUNNER_TEMP/action-smoke/action-injection-ran"
grep -Fqx "class Model(BaseModel):" "$RUNNER_TEMP/action-smoke/generated/model.py"
grep -Fqx " s: str" "$RUNNER_TEMP/action-smoke/generated/model.py"
92 changes: 71 additions & 21 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,46 +45,96 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/setup-python@v6.3.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: '3.14'

- uses: actions/cache@v6.0.0
- uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
with:
path: ~/.cache/pip
key: datamodel-codegen-${{ runner.os }}
key: datamodel-codegen-${{ runner.os }}-python-3.14

- name: Install datamodel-code-generator
env:
ACTION_REF: ${{ github.action_ref }}
INPUT_EXTRAS: ${{ inputs.extras }}
INPUT_VERSION: ${{ inputs.version }}
run: |
set -euo pipefail

- run: |
EXTRAS=""
if [ -n "${{ inputs.extras }}" ]; then
EXTRAS="[${{ inputs.extras }}]"
if [ -n "$INPUT_EXTRAS" ]; then
IFS="," read -r -a REQUESTED_EXTRAS <<< "$INPUT_EXTRAS"
NORMALIZED_EXTRAS=()
for EXTRA in "${REQUESTED_EXTRAS[@]}"; do
EXTRA="${EXTRA//[[:space:]]/}"
case "$EXTRA" in
graphql|http|validation|ruff|all)
NORMALIZED_EXTRAS+=("$EXTRA")
;;
*)
echo "::error::Unsupported extras value: $EXTRA"
exit 1
;;
esac
done
EXTRAS="[$(IFS=","; echo "${NORMALIZED_EXTRAS[*]}")]"
fi

VERSION="$INPUT_VERSION"
if [ -z "$VERSION" ] && [[ "$ACTION_REF" =~ ^[0-9]+\.[0-9]+\.[0-9]+(rc[0-9]+|\+backport-[0-9]+)?$ ]]; then
VERSION="$ACTION_REF"
fi

if [ -n "${{ inputs.version }}" ]; then
pip install "datamodel-code-generator${EXTRAS}==${{ inputs.version }}"
elif [[ "${{ github.action_ref }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
pip install "datamodel-code-generator${EXTRAS}==${{ github.action_ref }}"
else
pip install "datamodel-code-generator${EXTRAS}"
PACKAGE="datamodel-code-generator${EXTRAS}"
if [ -n "$VERSION" ]; then
PACKAGE="${PACKAGE}==${VERSION}"
fi

pip install "$PACKAGE"
shell: bash

- run: |
- name: Run datamodel-code-generator
env:
INPUT_CHECK: ${{ inputs.check }}
INPUT_EXTRA_ARGS: ${{ inputs.extra-args }}
INPUT_INPUT: ${{ inputs.input }}
INPUT_INPUT_FILE_TYPE: ${{ inputs.input-file-type }}
INPUT_OUTPUT: ${{ inputs.output }}
INPUT_OUTPUT_MODEL_TYPE: ${{ inputs.output-model-type }}
INPUT_PROFILE: ${{ inputs.profile }}
run: |
set -euo pipefail

ARGS=(
--input "${{ inputs.input }}"
--output "${{ inputs.output }}"
--input-file-type "${{ inputs.input-file-type }}"
--output-model-type "${{ inputs.output-model-type }}"
--input "$INPUT_INPUT"
--output "$INPUT_OUTPUT"
--input-file-type "$INPUT_INPUT_FILE_TYPE"
--output-model-type "$INPUT_OUTPUT_MODEL_TYPE"
)

if [ "${{ inputs.check }}" = "true" ]; then
if [ "$INPUT_CHECK" = "true" ]; then
ARGS+=(--check)
fi

if [ -n "${{ inputs.profile }}" ]; then
ARGS+=(--profile "${{ inputs.profile }}")
if [ -n "$INPUT_PROFILE" ]; then
ARGS+=(--profile "$INPUT_PROFILE")
fi

if [ -n "$INPUT_EXTRA_ARGS" ]; then
EXTRA_ARGS_FILE="$(mktemp)"
trap 'rm -f "$EXTRA_ARGS_FILE"' EXIT
python3 -c \
'import shlex, sys; sys.stdout.buffer.write(b"".join(arg.encode() + b"\0" for arg in shlex.split(sys.argv[1])))' \
"$INPUT_EXTRA_ARGS" > "$EXTRA_ARGS_FILE"

while IFS= read -r -d "" EXTRA_ARG; do
ARGS+=("$EXTRA_ARG")
done < "$EXTRA_ARGS_FILE"
rm -f "$EXTRA_ARGS_FILE"
trap - EXIT
fi

datamodel-codegen "${ARGS[@]}" ${{ inputs.extra-args }}
datamodel-codegen "${ARGS[@]}"
shell: bash
working-directory: ${{ inputs.working-directory }}
Loading