--- # yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json name: "Schemas" on: workflow_dispatch: schedule: - cron: "0 0 * * *" # Every day at midnight push: branches: ["main"] paths: [".forgejo/workflows/schemas.yaml"] jobs: publish: name: Schemas runs-on: ["docker-x86_64"] permissions: contents: read packages: write steps: - name: Checkout uses: https://github.com/actions/checkout@v4 with: fetch-depth: 0 - name: Setup Workflow Tools shell: bash run: | curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" chmod +x kubectl mv kubectl /usr/local/bin/ curl -LO "https://dl.min.io/client/mc/release/linux-amd64/mc" chmod +x mc mv mc /usr/local/bin/ - name: Setup Python run: | apt-get update apt-get install -y python3 python3-pip python3-yaml pip3 install --upgrade pip - name: Write kubeconfig id: kubeconfig uses: https://github.com/timheuer/base64-to-file@v1 with: encodedString: "${{ secrets.KUBECONFIG }}" fileName: kubeconfig fileDir: $GITHUB_WORKSPACE - name: Write mc id: mcconfig uses: https://github.com/timheuer/base64-to-file@v1 with: encodedString: "${{ secrets.MCCONFIG }}" fileName: config.json fileDir: $GITHUB_WORKSPACE - name: Extracting CRDs to yaml and converting to JSON schema env: KUBECONFIG: "${{ steps.kubeconfig.outputs.filePath }}" run: | # Create temp folder for CRDs TMP_CRD_DIR=$(mktemp -d) echo "Temp directory: $TMP_CRD_DIR" # Create final schemas directory SCHEMAS_DIR=$GITHUB_WORKSPACE/crdSchemas mkdir -p $SCHEMAS_DIR echo "Schemas directory: $SCHEMAS_DIR" # Create array to store CRD kinds and groups ORGANIZE_BY_GROUP=true declare -A CRD_GROUPS 2>/dev/null if [ $? -ne 0 ]; then # Array creation failed, signal to skip organization by group ORGANIZE_BY_GROUP=false fi # Extract CRDs from cluster NUM_OF_CRDS=0 while read -r crd do filename=${crd%% *} kubectl get crds "$filename" -o yaml > "$TMP_CRD_DIR/$filename.yaml" 2>&1 echo "Extracted CRD: $filename" resourceKind=$(grep "kind:" "$TMP_CRD_DIR/$filename.yaml" | awk 'NR==2{print $2}' | tr '[:upper:]' '[:lower:]') resourceGroup=$(grep "group:" "$TMP_CRD_DIR/$filename.yaml" | awk 'NR==1{print $2}') # Save name and group for later directory organization CRD_GROUPS["$resourceKind"]="$resourceGroup" let ++NUM_OF_CRDS done < <(kubectl get crds 2>&1 | sed -n '/NAME/,$p' | tail -n +2) echo numCRDs: $NUM_OF_CRDS cd $SCHEMAS_DIR # Download converter script curl https://raw.githubusercontent.com/yannh/kubeconform/master/scripts/openapi2jsonschema.py --output $TMP_CRD_DIR/openapi2jsonschema.py 2>/dev/null # Convert crds to jsonSchema python3 $TMP_CRD_DIR/openapi2jsonschema.py $TMP_CRD_DIR/*.yaml conversionResult=$? # Copy and rename files to support kubeval rm -rf $SCHEMAS_DIR/master-standalone mkdir -p $SCHEMAS_DIR/master-standalone cp $SCHEMAS_DIR/*.json $SCHEMAS_DIR/master-standalone find $SCHEMAS_DIR/master-standalone -name '*json' -exec bash -c ' mv -f $0 ${0/\_/-stable-}' {} \; # Organize schemas by group if [ $ORGANIZE_BY_GROUP == true ]; then for schema in $SCHEMAS_DIR/*.json do crdFileName=$(basename $schema .json) crdKind=${crdFileName%%_*} crdGroup=${CRD_GROUPS[$crdKind]} mkdir -p $crdGroup mv $schema ./$crdGroup done fi CYAN='\033[0;36m' GREEN='\033[0;32m' NC='\033[0m' # No Color if [ $conversionResult == 0 ]; then printf "${GREEN}Successfully converted $NUM_OF_CRDS CRDs to JSON schema${NC}\n" printf "\nTo validate a CR using various tools, run the relevant command:\n" printf "\n- ${CYAN}datree:${NC}\n\$ datree test /path/to/file\n" printf "\n- ${CYAN}kubeconform:${NC}\n\$ kubeconform -summary -output json -schema-location default -schema-location '$SCHEMAS_DIR/{{ .ResourceKind }}_{{ .ResourceAPIVersion }}.json' /path/to/file\n" printf "\n- ${CYAN}kubeval:${NC}\n\$ kubeval --additional-schema-locations file:\"$SCHEMAS_DIR\" /path/to/file\n\n" fi rm -rf $TMP_CRD_DIR - name: Deploy to Cloudflare R2 env: MC_CONFIG_DIR: $GITHUB_WORKSPACE shell: bash run: | mc cp --recursive $SCHEMAS_DIR r2-ks/kubernetes-schemas