diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..86b64d75 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,316 @@ +# Release pipeline for PAN-OS Terraform provider and pango Go SDK. +# +# Generates code, runs tests, pushes pango to main, and creates a PR +# in terraform-provider-panos. Merging that PR triggers GoReleaser +# via the auto-release workflow in the provider repo. +# +# Prerequisites: +# - GitHub App configured with contents:write on pango and terraform-provider-panos +# - Repository secrets: CODEGEN_APP_ID, CODEGEN_PRIVATE_KEY, CODEGEN_INSTALLATION_ID + +name: Release +run-name: "Release ${{ inputs.version_override || 'auto-detect' }}" + +on: + workflow_dispatch: + inputs: + version_override: + description: "Override auto-detected version (e.g. v2.1.0). Leave empty for auto-detection." + required: false + type: string + +permissions: + contents: write + +jobs: + generate-and-test: + name: Generate & Test + runs-on: ubuntu-latest + outputs: + version: ${{ steps.version.outputs.version }} + last_tag: ${{ steps.version.outputs.last_tag }} + since_date: ${{ steps.version.outputs.since_date }} + steps: + - name: Checkout pan-os-codegen + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5 + with: + go-version: "1.23" + + - name: Generate code + run: make codegen + + - name: Run codegen tests + run: make test/codegen + + - name: Run pango SDK tests + run: make test/pango + + - name: Determine version + id: version + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + LAST_TAG=$(gh release view --repo PaloAltoNetworks/terraform-provider-panos --json tagName -q '.tagName' 2>/dev/null || echo "v0.0.0") + SINCE_DATE=$(gh release view "$LAST_TAG" --repo PaloAltoNetworks/terraform-provider-panos --json publishedAt -q '.publishedAt' 2>/dev/null || echo "") + + if [ -n "${{ inputs.version_override }}" ]; then + VERSION="${{ inputs.version_override }}" + else + VERSION=$(bash scripts/determine-version.sh --last-tag "$LAST_TAG") + if [ "$VERSION" = "NO_BUMP" ]; then + echo "::error::No version-bumping commits found since $LAST_TAG" + exit 1 + fi + fi + + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "last_tag=$LAST_TAG" >> $GITHUB_OUTPUT + echo "since_date=$SINCE_DATE" >> $GITHUB_OUTPUT + echo "## Version" >> $GITHUB_STEP_SUMMARY + echo "- Current: $LAST_TAG" >> $GITHUB_STEP_SUMMARY + echo "- Next: $VERSION" >> $GITHUB_STEP_SUMMARY + + - name: Generate release notes + run: | + bash scripts/generate-release-notes.sh \ + "${{ steps.version.outputs.version }}" \ + "${{ steps.version.outputs.since_date }}" \ + > target/release-notes.md + echo "## Release Notes" >> $GITHUB_STEP_SUMMARY + cat target/release-notes.md >> $GITHUB_STEP_SUMMARY + + - name: Validate subcategories + run: | + SKIP_FILE="target/terraform/.subcategory-skip" + + # Find docs with empty or missing subcategory + MISSING=$(grep -rlE '^subcategory:\s*("")?\s*$' \ + target/terraform/docs/resources/ \ + target/terraform/docs/data-sources/ 2>/dev/null || true) + + MISSING_FIELD=$(find target/terraform/docs/resources target/terraform/docs/data-sources \ + -name "*.md" ! -exec grep -q "^subcategory:" {} \; -print 2>/dev/null || true) + + MISSING="${MISSING}${MISSING_FIELD}" + + # Filter out resources that explicitly opted out via skip_subcategory + if [ -f "$SKIP_FILE" ] && [ -n "$MISSING" ]; then + while IFS= read -r skip; do + MISSING=$(echo "$MISSING" | grep -v "/${skip}.md" || true) + done < "$SKIP_FILE" + fi + + if [ -n "$MISSING" ]; then + echo "::error::Resources missing subcategory:" + echo "$MISSING" + exit 1 + fi + echo "All resources have valid subcategories" + + - name: Upload generated code + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: generated-code + path: | + target/pango/ + target/terraform/ + target/release-notes.md + retention-days: 3 + if-no-files-found: error + + push-pango: + name: Push Pango SDK + needs: generate-and-test + runs-on: ubuntu-latest + outputs: + has_changes: ${{ steps.push.outputs.has_changes }} + steps: + - name: Generate GitHub App token + id: app-token + uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1 + with: + app-id: ${{ secrets.CODEGEN_APP_ID }} + private-key: ${{ secrets.CODEGEN_PRIVATE_KEY }} + installation-id: ${{ secrets.CODEGEN_INSTALLATION_ID }} + owner: PaloAltoNetworks + repositories: pango + + - name: Checkout pango + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + repository: PaloAltoNetworks/pango + token: ${{ steps.app-token.outputs.token }} + path: pango + + - name: Download generated code + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: generated-code + path: generated + + - name: Sync and push pango + id: push + run: | + # Copy generated SDK over (preserving non-generated files like .git) + rsync -av --exclude '.git' generated/pango/ pango/ + + cd pango + + if git diff --quiet && [ -z "$(git status --porcelain)" ]; then + echo "No changes in pango SDK" + echo "has_changes=false" >> $GITHUB_OUTPUT + exit 0 + fi + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add . + git commit -m "chore: auto-generated pango SDK" + git push + + echo "has_changes=true" >> $GITHUB_OUTPUT + echo "Pango SDK pushed to main" + + create-provider-pr: + name: Create Provider PR + needs: [generate-and-test, push-pango] + runs-on: ubuntu-latest + outputs: + pr_url: ${{ steps.create-pr.outputs.pr_url }} + steps: + - name: Generate GitHub App token + id: app-token + uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1 + with: + app-id: ${{ secrets.CODEGEN_APP_ID }} + private-key: ${{ secrets.CODEGEN_PRIVATE_KEY }} + installation-id: ${{ secrets.CODEGEN_INSTALLATION_ID }} + owner: PaloAltoNetworks + repositories: terraform-provider-panos + + - name: Set up Go + uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5 + with: + go-version: "1.23" + + - name: Checkout provider + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + repository: PaloAltoNetworks/terraform-provider-panos + token: ${{ steps.app-token.outputs.token }} + path: provider + + - name: Download generated code + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: generated-code + path: generated + + - name: Sync generated code to provider + run: | + # Copy generated terraform code over, excluding repo-specific files + rsync -av --exclude '.git' --exclude '.github' --exclude '.goreleaser.yml' \ + --exclude 'GNUmakefile' --exclude 'LICENSE' --exclude 'README.md' \ + --exclude 'SUPPORT.md' --exclude 'terraform-registry-manifest.json' \ + --exclude '.gitignore' --exclude 'scripts' \ + generated/terraform/ provider/ + + - name: Update pango dependency and generate docs + working-directory: provider + run: | + # Fetch the latest pango from main (just pushed in previous job) + go get github.com/PaloAltoNetworks/pango@main + go mod tidy + + # Generate terraform plugin documentation + go generate ./... + + - name: Validate subcategories in provider + run: | + SKIP_FILE="generated/terraform/.subcategory-skip" + + MISSING=$(grep -rlE '^subcategory:\s*("")?\s*$' \ + provider/docs/resources/ provider/docs/data-sources/ 2>/dev/null || true) + + if [ -f "$SKIP_FILE" ] && [ -n "$MISSING" ]; then + while IFS= read -r skip; do + MISSING=$(echo "$MISSING" | grep -v "/${skip}.md" || true) + done < "$SKIP_FILE" + fi + + if [ -n "$MISSING" ]; then + echo "::error::Resources missing subcategory after doc generation: $MISSING" + exit 1 + fi + + - name: Create PR + id: create-pr + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + VERSION: ${{ needs.generate-and-test.outputs.version }} + working-directory: provider + run: | + BRANCH="auto-release/${VERSION}" + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git checkout -b "$BRANCH" + git add . + + if git diff --staged --quiet; then + echo "::error::No changes to commit in provider" + exit 1 + fi + + git commit -m "chore(release): auto-generated ${VERSION}" + git push -u origin "$BRANCH" + + RELEASE_NOTES=$(cat ../generated/release-notes.md) + + PR_URL=$(gh pr create \ + --repo PaloAltoNetworks/terraform-provider-panos \ + --title "chore(release): ${VERSION}" \ + --body "$(cat < + ${RELEASE_NOTES} + + PREOF + )") + + echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT + echo "## Provider PR" >> $GITHUB_STEP_SUMMARY + echo "Created: $PR_URL" >> $GITHUB_STEP_SUMMARY + + tag-codegen: + name: Tag Codegen + needs: [generate-and-test, create-provider-pr] + runs-on: ubuntu-latest + steps: + - name: Checkout pan-os-codegen + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + fetch-depth: 0 + + - name: Tag release + env: + VERSION: ${{ needs.generate-and-test.outputs.version }} + run: | + git tag "release/${VERSION}" + git push origin "release/${VERSION}" + echo "Tagged pan-os-codegen with release/${VERSION}" diff --git a/assets/terraform/examples/resources/panos_virtual_wire/resource.tf b/assets/terraform/examples/resources/panos_virtual_wire/resource.tf index 7e8bf4de..2df80e8d 100644 --- a/assets/terraform/examples/resources/panos_virtual_wire/resource.tf +++ b/assets/terraform/examples/resources/panos_virtual_wire/resource.tf @@ -4,13 +4,13 @@ resource "panos_template" "tmpl" { } resource "panos_ethernet_interface" "iface1" { - location = { template = { name = resource.panos_template.template.name, vsys = "vsys1" } } + location = { template = { name = panos_template.tmpl.name, vsys = "vsys1" } } name = var.interface1 virtual_wire = {} } resource "panos_ethernet_interface" "iface2" { - location = { template = { name = resource.panos_template.template.name, vsys = "vsys1" } } + location = { template = { name = panos_template.tmpl.name, vsys = "vsys1" } } name = var.interface2 virtual_wire = {} } diff --git a/pkg/commands/codegen/codegen.go b/pkg/commands/codegen/codegen.go index 91c6f93b..900e76ca 100644 --- a/pkg/commands/codegen/codegen.go +++ b/pkg/commands/codegen/codegen.go @@ -6,6 +6,7 @@ import ( "log/slog" "os" "path/filepath" + "sort" "strings" "github.com/paloaltonetworks/pan-os-codegen/pkg/generate" @@ -106,9 +107,6 @@ func generateTfplugindocsTemplates(outputDir string, specMetadata map[string]pro // Generate template for resources if metadata.Flags&properties.TerraformSpecResource != 0 { subcategory := metadata.Subcategory - if subcategory == "" { - subcategory = "Uncategorized" - } resourceTemplate := fmt.Sprintf(`--- page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" @@ -151,9 +149,6 @@ Import is supported using the following syntax: // Generate template for data sources if metadata.Flags&properties.TerraformSpecDatasource != 0 { subcategory := metadata.Subcategory - if subcategory == "" { - subcategory = "Uncategorized" - } dataSourceTemplate := fmt.Sprintf(`--- page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" @@ -187,6 +182,24 @@ description: |- } slog.Info("Generated tfplugindocs templates", "resources", resourceCount, "dataSources", dataSourceCount, "templatesDir", templatesDir) + + // Write skip-list of resources that intentionally have no subcategory + var skipList []string + for suffix, metadata := range specMetadata { + if metadata.Subcategory == "" { + templateName := strings.TrimPrefix(suffix, "_") + skipList = append(skipList, templateName) + } + } + if len(skipList) > 0 { + sort.Strings(skipList) + skipPath := filepath.Join(outputDir, ".subcategory-skip") + if err := os.WriteFile(skipPath, []byte(strings.Join(skipList, "\n")+"\n"), 0644); err != nil { + return fmt.Errorf("error writing subcategory skip list: %w", err) + } + slog.Info("Wrote subcategory skip list", "count", len(skipList), "path", skipPath) + } + return nil } @@ -240,10 +253,17 @@ func (c *Command) Execute() error { return fmt.Errorf("%s sanity failed: %s", specPath, err) } - // Extract subcategory: use YAML override if present, otherwise derive from path + // Extract subcategory: use YAML override if present, otherwise derive from path. + // If skip_subcategory is set, leave it empty intentionally. if c.commandType == properties.CommandTypeTerraform { - if spec.TerraformProviderConfig.Subcategory == "" { - spec.TerraformProviderConfig.Subcategory = deriveSubcategoryFromPath(specPath) + if spec.TerraformProviderConfig.SkipSubcategory { + spec.TerraformProviderConfig.Subcategory = "" + } else if spec.TerraformProviderConfig.Subcategory == "" { + subcategory := deriveSubcategoryFromPath(specPath) + if subcategory == "" { + return fmt.Errorf("%s: no subcategory found — set 'subcategory' in the spec or use 'skip_subcategory: true' if intentional", specPath) + } + spec.TerraformProviderConfig.Subcategory = subcategory } } diff --git a/pkg/properties/normalized.go b/pkg/properties/normalized.go index 84582218..d545c7d4 100644 --- a/pkg/properties/normalized.go +++ b/pkg/properties/normalized.go @@ -62,6 +62,7 @@ const ( type TerraformProviderConfig struct { Description string `json:"description" yaml:"description"` Subcategory string `json:"subcategory" yaml:"subcategory"` + SkipSubcategory bool `json:"skip_subcategory" yaml:"skip_subcategory"` Ephemeral bool `json:"ephemeral" yaml:"ephemeral"` Action bool `json:"action" yaml:"action"` CustomValidation bool `json:"custom_validation" yaml:"custom_validation"` @@ -705,6 +706,7 @@ func schemaToSpec(object object.Object) (*Normalization, error) { SkipResource: object.TerraformConfig.SkipResource, SkipDatasource: object.TerraformConfig.SkipDatasource, SkipDatasourceListing: object.TerraformConfig.SkipdatasourceListing, + SkipSubcategory: object.TerraformConfig.SkipSubcategory, ResourceType: TerraformResourceType(object.TerraformConfig.ResourceType), XmlNode: object.TerraformConfig.XmlNode, CustomFuncs: object.TerraformConfig.CustomFunctions, diff --git a/pkg/schema/object/object.go b/pkg/schema/object/object.go index 0e6ccbda..857a2024 100644 --- a/pkg/schema/object/object.go +++ b/pkg/schema/object/object.go @@ -43,6 +43,7 @@ type TerraformConfig struct { SkipResource bool `yaml:"skip_resource"` SkipDatasource bool `yaml:"skip_datasource"` SkipdatasourceListing bool `yaml:"skip_datasource_listing"` + SkipSubcategory bool `yaml:"skip_subcategory"` ResourceType TerraformResourceType `yaml:"resource_type"` XmlNode *string `yaml:"xml_node"` CustomFunctions map[string]bool `yaml:"custom_functions"` diff --git a/scripts/determine-version.sh b/scripts/determine-version.sh new file mode 100755 index 00000000..0e5beff9 --- /dev/null +++ b/scripts/determine-version.sh @@ -0,0 +1,120 @@ +#!/bin/bash +# +# Determines the next version for terraform-provider-panos based on +# conventional commits in pan-os-codegen since the last provider release. +# +# Custom release rules (non-standard semver): +# feat(MAJOR): ... -> major bump +# BREAKING CHANGE in footer -> minor bump (not major!) +# feat: ... -> patch bump (not minor!) +# fix: ... -> patch bump +# +# Usage: +# determine-version.sh # auto-detect from local repos +# determine-version.sh --provider-dir # specify provider repo path +# determine-version.sh --last-tag # specify last tag directly (for CI) + +set -euo pipefail + +PROVIDER_DIR="" +LAST_TAG="" + +while [[ $# -gt 0 ]]; do + case $1 in + --provider-dir) PROVIDER_DIR="$2"; shift 2 ;; + --last-tag) LAST_TAG="$2"; shift 2 ;; + *) echo "Unknown argument: $1" >&2; exit 1 ;; + esac +done + +# Resolve the last tag +if [ -z "$LAST_TAG" ]; then + if [ -n "$PROVIDER_DIR" ] && [ -d "$PROVIDER_DIR/.git" ]; then + LAST_TAG=$(cd "$PROVIDER_DIR" && git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") + elif command -v gh &>/dev/null; then + LAST_TAG=$(gh release view --repo PaloAltoNetworks/terraform-provider-panos --json tagName -q '.tagName' 2>/dev/null || echo "v0.0.0") + else + echo "Error: cannot determine last tag. Provide --last-tag or --provider-dir." >&2 + exit 1 + fi +fi + +CURRENT_VERSION="${LAST_TAG#v}" + +# Determine the anchor date for codegen commits +if [ "$LAST_TAG" = "v0.0.0" ]; then + SINCE_FLAG="" +else + TAG_DATE="" + if [ -n "$PROVIDER_DIR" ] && [ -d "$PROVIDER_DIR/.git" ]; then + TAG_DATE=$(cd "$PROVIDER_DIR" && git log -1 --format="%aI" "$LAST_TAG" 2>/dev/null || echo "") + fi + if [ -z "$TAG_DATE" ] && command -v gh &>/dev/null; then + TAG_DATE=$(gh release view "$LAST_TAG" --repo PaloAltoNetworks/terraform-provider-panos --json publishedAt -q '.publishedAt' 2>/dev/null || echo "") + fi + if [ -n "$TAG_DATE" ]; then + SINCE_FLAG="--after=$TAG_DATE" + else + echo "Warning: could not determine tag date, scanning all commits" >&2 + SINCE_FLAG="" + fi +fi + +IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION" + +BUMP="none" + +while IFS= read -r line; do + [ -z "$line" ] && continue + + # Highest priority: feat(MAJOR) -> major bump + if echo "$line" | grep -qiE '^feat\(MAJOR\)'; then + BUMP="major" + break + fi + + # BREAKING CHANGE in commit body -> minor bump + if echo "$line" | grep -q 'BREAKING CHANGE'; then + if [ "$BUMP" != "major" ]; then + BUMP="minor" + fi + continue + fi + + # feat (but not feat(MAJOR)) -> patch bump + if echo "$line" | grep -qE '^feat(\(|:)' && ! echo "$line" | grep -qiE '^feat\(MAJOR\)'; then + if [ "$BUMP" = "none" ]; then + BUMP="patch" + fi + continue + fi + + # fix -> patch bump + if echo "$line" | grep -qE '^fix(\(|:)'; then + if [ "$BUMP" = "none" ]; then + BUMP="patch" + fi + continue + fi +done <<< "$(git log $SINCE_FLAG --format="%s%n%b" HEAD 2>/dev/null)" + +case $BUMP in + major) + MAJOR=$((MAJOR + 1)) + MINOR=0 + PATCH=0 + ;; + minor) + MINOR=$((MINOR + 1)) + PATCH=0 + ;; + patch) + PATCH=$((PATCH + 1)) + ;; + none) + echo "NO_BUMP" + exit 0 + ;; +esac + +echo "v${MAJOR}.${MINOR}.${PATCH}" diff --git a/scripts/generate-release-notes.sh b/scripts/generate-release-notes.sh new file mode 100755 index 00000000..909b45c8 --- /dev/null +++ b/scripts/generate-release-notes.sh @@ -0,0 +1,99 @@ +#!/bin/bash +# +# Generates markdown release notes from conventional commits in pan-os-codegen. +# +# Usage: +# generate-release-notes.sh [since-date] +# +# If since-date is provided, only includes commits after that date. +# Otherwise includes all commits. + +set -euo pipefail + +VERSION="${1:?Usage: generate-release-notes.sh [since-date]}" +SINCE_DATE="${2:-}" + +LOG_ARGS="--format=%s" +if [ -n "$SINCE_DATE" ]; then + LOG_ARGS="$LOG_ARGS --after=$SINCE_DATE" +fi + +# Collect commits into arrays by type +FEATS=() +FIXES=() +BREAKING=() + +while IFS= read -r subject; do + [ -z "$subject" ] && continue + + # feat(MAJOR) -> breaking + if echo "$subject" | grep -qiE '^feat\(MAJOR\)'; then + msg=$(echo "$subject" | sed 's/^feat(MAJOR)[!]*: //') + BREAKING+=("- $msg") + continue + fi + + # feat -> feature + if echo "$subject" | grep -qE '^feat(\(|:)'; then + scope=$(echo "$subject" | sed -n 's/^feat(\([^)]*\))[!]*:.*/\1/p') + msg=$(echo "$subject" | sed 's/^feat([^)]*)[!]*: //' | sed 's/^feat[!]*: //') + if [ -n "$scope" ]; then + FEATS+=("- **$scope**: $msg") + else + FEATS+=("- $msg") + fi + continue + fi + + # fix -> bug fix + if echo "$subject" | grep -qE '^fix(\(|:)'; then + scope=$(echo "$subject" | sed -n 's/^fix(\([^)]*\))[!]*:.*/\1/p') + msg=$(echo "$subject" | sed 's/^fix([^)]*)[!]*: //' | sed 's/^fix[!]*: //') + if [ -n "$scope" ]; then + FIXES+=("- **$scope**: $msg") + else + FIXES+=("- $msg") + fi + continue + fi + + # Skip chore, docs, ci, test, refactor, style, build — internal commits +done < <(git log $LOG_ARGS HEAD 2>/dev/null) + +# Also scan commit bodies for BREAKING CHANGE +while IFS= read -r body_line; do + if echo "$body_line" | grep -q 'BREAKING CHANGE:'; then + msg=$(echo "$body_line" | sed 's/BREAKING CHANGE: //') + BREAKING+=("- $msg") + fi +done < <(git log ${SINCE_DATE:+--after=$SINCE_DATE} --format="%b" HEAD 2>/dev/null) + +# Output +echo "## What's Changed in ${VERSION}" +echo "" + +if [ ${#BREAKING[@]} -gt 0 ]; then + echo "### Breaking Changes" + echo "" + printf '%s\n' "${BREAKING[@]}" + echo "" +fi + +if [ ${#FEATS[@]} -gt 0 ]; then + echo "### Features" + echo "" + printf '%s\n' "${FEATS[@]}" + echo "" +fi + +if [ ${#FIXES[@]} -gt 0 ]; then + echo "### Bug Fixes" + echo "" + printf '%s\n' "${FIXES[@]}" + echo "" +fi + +if [ ${#BREAKING[@]} -eq 0 ] && [ ${#FEATS[@]} -eq 0 ] && [ ${#FIXES[@]} -eq 0 ]; then + echo "No notable changes." + echo "" +fi diff --git a/specs/actions/commit.yaml b/specs/actions/commit.yaml index 15001e0c..5526ad9d 100644 --- a/specs/actions/commit.yaml +++ b/specs/actions/commit.yaml @@ -1,6 +1,7 @@ name: commit terraform_provider_config: description: Commit Action + skip_subcategory: true skip_resource: true skip_datasource: true resource_type: custom diff --git a/specs/actions/push_to_devices.yaml b/specs/actions/push_to_devices.yaml index b91ba8dc..6580074f 100644 --- a/specs/actions/push_to_devices.yaml +++ b/specs/actions/push_to_devices.yaml @@ -1,6 +1,7 @@ name: push_to_devices terraform_provider_config: description: Push to Devices Action + skip_subcategory: true skip_resource: true skip_datasource: true resource_type: custom