From f107f0be845e28135aad5d3432c919c63760b8b0 Mon Sep 17 00:00:00 2001 From: SignalRichard <20459042+SignalRichard@users.noreply.github.com> Date: Mon, 8 May 2023 14:57:27 -0400 Subject: [PATCH] build: Add docs, goreleaser, and GH actions --- .editorconfig | 20 ++++++++ .github/workflows/release.yml | 51 +++++++++++++++++++++ .goreleaser.yml | 63 +++++++++++++++++++++++++ Initialize-TerraformDocumentation.ps1 | 27 ----------- LICENSE | 21 +++++++++ Makefile | 37 --------------- README.md | 66 +++++++++++++-------------- docs/data-sources/answer.md | 34 ++++++++++++++ docs/data-sources/article.md | 32 +++++++++++++ docs/data-sources/filter.md | 37 +++++++++++++++ docs/data-sources/question.md | 34 ++++++++++++++ docs/index.md | 57 +++++++++++++++++++++++ docs/resources/answer.md | 43 +++++++++++++++++ docs/resources/article.md | 44 ++++++++++++++++++ docs/resources/filter.md | 35 ++++++++++++++ docs/resources/question.md | 41 +++++++++++++++++ go.mod | 12 +++-- go.sum | 16 +++++++ main.go | 3 ++ stackoverflow/data_answer.go | 10 ++-- stackoverflow/data_article.go | 10 ++-- stackoverflow/data_filter.go | 5 +- stackoverflow/data_question.go | 10 ++-- stackoverflow/provider.go | 5 +- stackoverflow/resource_answer.go | 15 +++--- stackoverflow/resource_article.go | 25 ++++++---- stackoverflow/resource_question.go | 16 ++++--- terraform-registry-manifest.json | 6 +++ tools/tools.go | 8 ++++ 29 files changed, 642 insertions(+), 141 deletions(-) create mode 100644 .editorconfig create mode 100644 .github/workflows/release.yml create mode 100644 .goreleaser.yml delete mode 100644 Initialize-TerraformDocumentation.ps1 create mode 100644 LICENSE delete mode 100644 Makefile create mode 100644 docs/data-sources/answer.md create mode 100644 docs/data-sources/article.md create mode 100644 docs/data-sources/filter.md create mode 100644 docs/data-sources/question.md create mode 100644 docs/index.md create mode 100644 docs/resources/answer.md create mode 100644 docs/resources/article.md create mode 100644 docs/resources/filter.md create mode 100644 docs/resources/question.md create mode 100644 terraform-registry-manifest.json create mode 100644 tools/tools.go diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c799db0 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +# defaults +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{yaml,yml}] +indent_style = space +indent_size = 2 + +# Go +# https://golang.org/cmd/gofmt/ +[{go.mod,*.go}] +indent_style = tab diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..5640174 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,51 @@ +# This GitHub action can publish assets for release when a tag is created. +# Currently its setup to run on any tag that matches the pattern "v*" (ie. v0.1.0). +# +# This uses an action (crazy-max/ghaction-import-gpg) that assumes you set your +# private key in the `GPG_PRIVATE_KEY` secret and passphrase in the `PASSPHRASE` +# secret. If you would rather own your own GPG handling, please fork this action +# or use an alternative one for key handling. +# +# You will need to pass the `--batch` flag to `gpg` in your signing step +# in `goreleaser` to indicate this is being used in a non-interactive mode. +# +name: release +on: + push: + tags: + - 'v*' +permissions: + contents: write +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - + name: Unshallow + run: git fetch --prune --unshallow + - + name: Set up Go + uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 + with: + go-version-file: 'go.mod' + cache: true + - + name: Import GPG key + uses: crazy-max/ghaction-import-gpg@111c56156bcc6918c056dbef52164cfa583dc549 # v5.2.0 + id: import_gpg + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.PASSPHRASE }} + - + name: Run GoReleaser + uses: goreleaser/goreleaser-action@f82d6c1c344bcacabba2c841718984797f664a6b # v4.2.0 + with: + version: latest + args: release --rm-dist + env: + GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} + # GitHub sets this automatically + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..7281d34 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,63 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +# Visit https://goreleaser.com for documentation on how to customize this +# behavior. +before: + hooks: + # this is just an example and not a requirement for provider building/publishing + - go mod tidy +builds: +- env: + # goreleaser does not work with CGO, it could also complicate + # usage by users in CI/CD systems like Terraform Cloud where + # they are unable to install libraries. + - CGO_ENABLED=0 + mod_timestamp: '{{ .CommitTimestamp }}' + flags: + - -trimpath + ldflags: + - '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}' + goos: + - freebsd + - windows + - linux + - darwin + goarch: + - amd64 + - '386' + - arm + - arm64 + ignore: + - goos: darwin + goarch: '386' + binary: '{{ .ProjectName }}_v{{ .Version }}' +archives: +- format: zip + name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' +checksum: + extra_files: + - glob: 'terraform-registry-manifest.json' + name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' + name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS' + algorithm: sha256 +signs: + - artifacts: checksum + args: + # if you are using this in a GitHub action or some other automated pipeline, you + # need to pass the batch flag to indicate its not interactive. + - "--batch" + - "--local-user" + - "{{ .Env.GPG_FINGERPRINT }}" # set this environment variable for your signing key + - "--output" + - "${signature}" + - "--detach-sign" + - "${artifact}" +release: + extra_files: + - glob: 'terraform-registry-manifest.json' + name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' + # If you want to manually examine the release before its live, uncomment this line: + # draft: true +changelog: + skip: true diff --git a/Initialize-TerraformDocumentation.ps1 b/Initialize-TerraformDocumentation.ps1 deleted file mode 100644 index 2c20cea..0000000 --- a/Initialize-TerraformDocumentation.ps1 +++ /dev/null @@ -1,27 +0,0 @@ -param( - [string] $Path, - [string] $OutputPath, - [string[]] $Tags, - [string] $FilterResource -) - -$Pattern = "[^a-zA-Z0-9]" -$ResourcesJson = "{" -Get-ChildItem -Path $Path -Filter "*.md" | ForEach-Object { - $Resource = @{ - stackoverflow_article = @{ - "$($_.BaseName -Replace $Pattern, '_')" = @{ - article_type = "knowledge-article" - title = $_.BaseName - body_markdown = "`${file(`"$($_.FullName -replace "\\", "/")`")}" - tags = $Tags - filter = "`${$FilterResource}" - } - } - } - $ResourcesJson += "`"resource`": " + (ConvertTo-Json -Depth 10 -InputObject $Resource) + "," -} -$ResourcesJson = $ResourcesJson.TrimEnd(',') -$ResourcesJson += "}" - -$ResourcesJson | Out-File -FilePath (Join-Path -Path $OutputPath -ChildPath "$(Split-Path -Path $Path -Leaf).tf.json") diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c6d3da2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Stack Overflow + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile deleted file mode 100644 index ba7102d..0000000 --- a/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -TEST?=$$(go list ./... | grep -v 'vendor') -HOSTNAME=hashicorp.com -NAMESPACE=edu -NAME=hashicups -BINARY=terraform-provider-${NAME} -VERSION=0.1 -OS_ARCH=darwin_amd64 - -default: install - -build: - go build -o ${BINARY} - -release: - GOOS=darwin GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_darwin_amd64 - GOOS=freebsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_freebsd_386 - GOOS=freebsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_freebsd_amd64 - GOOS=freebsd GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_freebsd_arm - GOOS=linux GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_linux_386 - GOOS=linux GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_linux_amd64 - GOOS=linux GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_linux_arm - GOOS=openbsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_openbsd_386 - GOOS=openbsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_openbsd_amd64 - GOOS=solaris GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_solaris_amd64 - GOOS=windows GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_windows_386 - GOOS=windows GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_windows_amd64 - -install: build - mkdir -p ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${OS_ARCH} - mv ${BINARY} ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${OS_ARCH} - -test: - go test -i $(TEST) || exit 1 - echo $(TEST) | xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4 - -testacc: - TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m \ No newline at end of file diff --git a/README.md b/README.md index 522aa96..38755cd 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,43 @@ -# Terraform Provider Stack Overflow +# Terraform Provider for Stack Overflow -Run the following command to build the provider +The Terraform Provider for Stack Overflow is a Terraform plugin provider that allows you to manage questions, answers, and articles for your Stack Overflow for Teams. -```powershell -# Windows -go build -o terraform-provider-stackoverflow.exe -cp terraform-provider-stackoverflow.exe ~/go/bin -``` +## Using the Provider +--------------------- -Create a `terraform.rc` file in the %APPDATA% directory. +To use a released version of the Terraform provider in your environment, run `terraform init` and Terraform will automatically install the provider from the Terraform Registry. To specify a particular provider version when installing released providers, see the [Terraform documentation on provider versioning](https://www.terraform.io/docs/configuration/providers.html#version-provider-versions). -```powershell -cd $env:APPDATA -mk terraform.rc -``` +## Example +---------- -Add the following content to the `terraform.rc` file: +```terraform +provider "stackoverflow" { + team_name = "my-team-name" + access_token = "xxxx" + default_tags = ["terraform"] +} -``` -provider_installation { - dev_overrides { - "registry.terraform.io/hashicorp/stackoverflow" = "C:/Users/rbolhofer/go/bin" - } - direct {} +resource "stackoverflow_filter" "filter" { } -``` -## Test sample configuration +resource "stackoverflow_article" "article" { + article_type = "announcement" + title = "Terraform Provider for Stack Overflow is available!" + body_markdown = "Look for the Stack Overflow provider in the Terraform registry" + tags = ["example"] + filter = stackoverflow_filter.filter.id +} -In a new directory, create a file named `main.tf` and add the following content: +resource "stackoverflow_question" "question" { + title = "Stack Overflow Terraform Provider" + body_markdown = "What is the Terraform Provider for Stack Overflow?" + tags = ["example"] + filter = stackoverflow_filter.filter.id +} -``` -resource "stackoverflow_article" "test_article" { - article_type = "knowledge-article" - title = "Test Article" - body_markdown = "# Hello World" - tags = ["test"] +resource "stackoverflow_answer" "answer" { + question_id = stackoverflow_question.question.id + body_markdown = "It is a Terraform plugin provider to manage resources in Stack Overflow for Teams" + filter = stackoverflow_filter.filter.id } ``` - -Then initialize and run Terraform: - -```powershell -terraform init -terraform plan -out terraform.tfplan -``` \ No newline at end of file diff --git a/docs/data-sources/answer.md b/docs/data-sources/answer.md new file mode 100644 index 0000000..57f8eb3 --- /dev/null +++ b/docs/data-sources/answer.md @@ -0,0 +1,34 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "stackoverflow_answer Data Source - terraform-provider-stackoverflow" +subcategory: "" +description: |- + +--- + +# stackoverflow_answer (Data Source) + +The `answer` data source allows for referencing an existing answer in Stack Overflow. + +## Example + +``` +data "stackoverflow_answer" "answer" { + answer_id = 1 + filter = "XXXX" +} +``` + + +## Schema + +### Required + +- `answer_id` (Number) The identifier for the answer +- `filter` (String) The API filter to use + +### Read-Only + +- `id` (String) The ID of this resource. + + diff --git a/docs/data-sources/article.md b/docs/data-sources/article.md new file mode 100644 index 0000000..fa4fe99 --- /dev/null +++ b/docs/data-sources/article.md @@ -0,0 +1,32 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "stackoverflow_article Data Source - terraform-provider-stackoverflow" +subcategory: "" +description: |- + +--- + +# stackoverflow_article (Data Source) + +The `article` data source allows for referencing an existing article in Stack Overflow. + +``` +data "stackoverflow_article" "article" { + article_id = 1 + filter = "XXXX" +} +``` + + +## Schema + +### Required + +- `article_id` (Number) The identifier for the article +- `filter` (String) The API filter to use + +### Read-Only + +- `id` (String) The ID of this resource. + + diff --git a/docs/data-sources/filter.md b/docs/data-sources/filter.md new file mode 100644 index 0000000..1c27a25 --- /dev/null +++ b/docs/data-sources/filter.md @@ -0,0 +1,37 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "stackoverflow_filter Data Source - terraform-provider-stackoverflow" +subcategory: "" +description: |- + +--- + +# stackoverflow_filter (Data Source) + +The `filter` data source allows for referencing an existing filter in Stack Overflow. This can be used to import an existing filter that +may not have the proper fields returned for the types used by the provider. It is recommended to only import filters that have been created +by the Terraform Provider for Stack Overflow to ensure that the correct fields will be returned by the API. See the following article for +more details about [custom filters](https://api.stackexchange.com/docs/filters) in the Stack Overflow API. + +As an alternative to importing an existing filter, users can export the filter ID using Terraform output and use a remote state data source +to reuse a single filter across multiple Terraform repositories. + +## Example +``` +data "stackoverflow_filter" "filter" { + filter = "XXXX" +} +``` + + +## Schema + +### Required + +- `filter` (String) The identifier for the filter + +### Read-Only + +- `id` (String) The ID of this resource. + + diff --git a/docs/data-sources/question.md b/docs/data-sources/question.md new file mode 100644 index 0000000..1917c3c --- /dev/null +++ b/docs/data-sources/question.md @@ -0,0 +1,34 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "stackoverflow_question Data Source - terraform-provider-stackoverflow" +subcategory: "" +description: |- + +--- + +# stackoverflow_question (Data Source) + +The `question` data source allows for referencing an existing question in Stack Overflow. + +## Example + +``` +data "stackoverflow_question" "question" { + filter = "XXXX" + question_id = 1 +} +``` + + +## Schema + +### Required + +- `filter` (String) The API filter to use +- `question_id` (Number) The identifier for the question + +### Read-Only + +- `id` (String) The ID of this resource. + + diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..79c854d --- /dev/null +++ b/docs/index.md @@ -0,0 +1,57 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "stackoverflow Provider" +subcategory: "" +description: |- + +--- + +# Stack Overflow Provider + +Use the Stack Overflow provider to manage questions, answers, and articles for your Stack Overflow for Teams. You must configure the provider with the proper credentials before you can use it. + +## Example Usage + +This example demonstrates the usage of the provider by setting up the provider configuration and several different resource types. Note the usage of the filter resource which is required when managing all other resource types. + +```terraform +provider "stackoverflow" { + team_name = "my-team-name" + access_token = "xxxx" + default_tags = ["terraform"] +} + +resource "stackoverflow_filter" "filter" { +} + +resource "stackoverflow_article" "article" { + article_type = "announcement" + title = "Terraform Provider for Stack Overflow is available!" + body_markdown = "Look for the Stack Overflow provider in the Terraform registry" + tags = ["example"] + filter = stackoverflow_filter.filter.id +} + +resource "stackoverflow_question" "question" { + title = "Stack Overflow Terraform Provider" + body_markdown = "What is the Terraform Provider for Stack Overflow?" + tags = ["example"] + filter = stackoverflow_filter.filter.id +} + +resource "stackoverflow_answer" "answer" { + question_id = stackoverflow_question.question.id + body_markdown = "It is a Terraform plugin provider to manage resources in Stack Overflow for Teams" + filter = stackoverflow_filter.filter.id +} +``` + + +## Argument Reference + +| Name | Required | Type | Environment Variable | Default | Description | +| ---- | -------- | ---- | -------------------- | ------- | ----------- | +| `access_token` | Required | `string` | `STACK_OVERFLOW_ACCESS_TOKEN` | | The Stack Overflow API access token | +| `team_name` | Required | `string` | `STACK_OVERFLOW_TEAM` | | The Stack Overflow team name | +| `base_url` | Optional | `string` | `STACK_OVERFLOW_API_URL` | `https://api.stackoverflowteams.com/2.3/` | The base URL for the Stack Overflow API | +| `default_tags` | Optional | `string[]` | | | A list of tags to automatically associate with any resources that support tags | diff --git a/docs/resources/answer.md b/docs/resources/answer.md new file mode 100644 index 0000000..6acf154 --- /dev/null +++ b/docs/resources/answer.md @@ -0,0 +1,43 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "stackoverflow_answer Resource - terraform-provider-stackoverflow" +subcategory: "" +description: |- + +--- + +# stackoverflow_answer (Resource) + +Manages an answer and associates it to the related question. + +## Example + +``` +resource "stackoverflow_question" "question" { + title = "Stack Overflow Terraform Provider" + body_markdown = "What is the Terraform Provider for Stack Overflow?" + tags = ["example"] + filter = "XXXX" +} + +resource "stackoverflow_answer" "answer" { + question_id = stackoverflow_question.question.id + body_markdown = "It is a Terraform plugin provider to manage resources in Stack Overflow for Teams" + filter = "XXXX" +} +``` + + +## Schema + +### Required + +- `body_markdown` (String) The answer content in Markdown format +- `filter` (String) The API filter to use +- `question_id` (Number) The question identifier that this answer applies to + +### Read-Only + +- `id` (String) The ID of this resource. + + diff --git a/docs/resources/article.md b/docs/resources/article.md new file mode 100644 index 0000000..f864ace --- /dev/null +++ b/docs/resources/article.md @@ -0,0 +1,44 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "stackoverflow_article Resource - terraform-provider-stackoverflow" +subcategory: "" +description: |- + +--- + +# stackoverflow_article (Resource) + +Manages a long form article. At least one tag is required which can be either be set as a default tag on the provider or set at the resource level. + +## Example + +``` +resource "stackoverflow_article" "article" { + article_type = "announcement" + title = "Terraform Provider for Stack Overflow is available!" + body_markdown = "Look for the Stack Overflow provider in the Terraform registry" + tags = ["example"] + filter = "XXXX" +} +``` + + + +## Schema + +### Required + +- `article_type` (String) The type of article. Must be one of `knowledge-article`, `announcement`, `how-to-guide`, `policy` +- `filter` (String) The API filter to use +- `title` (String) The title of the article + +### Optional + +- `body_markdown` (String) The article content in Markdown format +- `tags` (List of String) The set of tags to be associated with the article + +### Read-Only + +- `id` (String) The ID of this resource. + + diff --git a/docs/resources/filter.md b/docs/resources/filter.md new file mode 100644 index 0000000..bcded13 --- /dev/null +++ b/docs/resources/filter.md @@ -0,0 +1,35 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "stackoverflow_filter Resource - terraform-provider-stackoverflow" +subcategory: "" +description: |- + +--- + +# stackoverflow_filter (Resource) + +Manages a filter used to interact with the underlying Stack Overflow API. This resource has no fields and is automatically created with the required return fields. It is recommended to create one filter per set of Terraform IaC or reuse a filter across Terraform IaC code sets by exporting the filter and using a remote state data source to access the filter identifier. + +## Example + +``` +resource "stackoverflow_filter" "filter" { +} + +resource "stackoverflow_article" "article" { + article_type = "announcement" + title = "Terraform Provider for Stack Overflow is available!" + body_markdown = "Look for the Stack Overflow provider in the Terraform registry" + tags = ["example"] + filter = stackoverflow_filter.filter.id +} +``` + + +## Schema + +### Read-Only + +- `id` (String) The ID of this resource. + + diff --git a/docs/resources/question.md b/docs/resources/question.md new file mode 100644 index 0000000..04954b8 --- /dev/null +++ b/docs/resources/question.md @@ -0,0 +1,41 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "stackoverflow_question Resource - terraform-provider-stackoverflow" +subcategory: "" +description: |- + +--- + +# stackoverflow_question (Resource) + +Manages a question. At least one tag is required which can be either be set as a default tag on the provider or set at the resource level. + +## Example + +``` +resource "stackoverflow_question" "question" { + title = "Stack Overflow Terraform Provider" + body_markdown = "What is the Terraform Provider for Stack Overflow?" + tags = ["example"] + filter = stackoverflow_filter.filter.id +} +``` + + +## Schema + +### Required + +- `body_markdown` (String) The question content in Markdown format +- `filter` (String) The API filter to use +- `title` (String) The title of the article + +### Optional + +- `tags` (List of String) The set of tags to be associated with the article + +### Read-Only + +- `id` (String) The ID of this resource. + + diff --git a/go.mod b/go.mod index 162e4ce..36aa29f 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module terraform-provider-stackoverflow go 1.19 require ( - github.com/hashicorp/terraform-plugin-docs v0.13.0 + github.com/hashicorp/terraform-plugin-docs v0.14.1 github.com/hashicorp/terraform-plugin-sdk/v2 v2.25.0 ) @@ -27,6 +27,8 @@ require ( github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/spf13/afero v1.2.2 // indirect github.com/ulikunitz/xz v0.5.8 // indirect + github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/zclconf/go-cty-yaml v1.0.2 // indirect go.opencensus.io v0.22.4 // indirect golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect @@ -61,7 +63,7 @@ require ( github.com/hashicorp/hc-install v0.5.0 // indirect github.com/hashicorp/hcl/v2 v2.16.1 // indirect github.com/hashicorp/logutils v1.0.0 // indirect - github.com/hashicorp/terraform-exec v0.17.3 // indirect + github.com/hashicorp/terraform-exec v0.18.1 // indirect github.com/hashicorp/terraform-json v0.15.0 // indirect github.com/hashicorp/terraform-plugin-go v0.14.3 // indirect github.com/hashicorp/terraform-plugin-log v0.8.0 // indirect @@ -71,8 +73,8 @@ require ( github.com/huandu/xstrings v1.3.2 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/kr/pretty v0.3.1 - github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect github.com/mitchellh/cli v1.1.5 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect @@ -87,7 +89,7 @@ require ( github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect - github.com/zclconf/go-cty v1.12.1 // indirect + github.com/zclconf/go-cty v1.13.0 // indirect golang.org/x/crypto v0.6.0 // indirect golang.org/x/net v0.6.0 // indirect golang.org/x/sys v0.5.0 // indirect diff --git a/go.sum b/go.sum index 0bbc990..6fce125 100644 --- a/go.sum +++ b/go.sum @@ -243,10 +243,14 @@ github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7 github.com/hashicorp/terraform-exec v0.13.3/go.mod h1:SSg6lbUsVB3DmFyCPjBPklqf6EYGX0TlQ6QTxOlikDU= github.com/hashicorp/terraform-exec v0.17.3 h1:MX14Kvnka/oWGmIkyuyvL6POx25ZmKrjlaclkx3eErU= github.com/hashicorp/terraform-exec v0.17.3/go.mod h1:+NELG0EqQekJzhvikkeQsOAZpsw0cv/03rbeQJqscAI= +github.com/hashicorp/terraform-exec v0.18.1 h1:LAbfDvNQU1l0NOQlTuudjczVhHj061fNX5H8XZxHlH4= +github.com/hashicorp/terraform-exec v0.18.1/go.mod h1:58wg4IeuAJ6LVsLUeD2DWZZoc/bYi6dzhLHzxM41980= github.com/hashicorp/terraform-json v0.10.0/go.mod h1:3defM4kkMfttwiE7VakJDwCd4R+umhSQnvJwORXbprE= github.com/hashicorp/terraform-json v0.15.0 h1:/gIyNtR6SFw6h5yzlbDbACyGvIhKtQi8mTsbkNd79lE= github.com/hashicorp/terraform-json v0.15.0/go.mod h1:+L1RNzjDU5leLFZkHTFTbJXaoqUC6TqXlFgDoOXrtvk= github.com/hashicorp/terraform-plugin-docs v0.13.0/go.mod h1:W0oCmHAjIlTHBbvtppWHe8fLfZ2BznQbuv8+UD8OucQ= +github.com/hashicorp/terraform-plugin-docs v0.14.1 h1:MikFi59KxrP/ewrZoaowrB9he5Vu4FtvhamZFustiA4= +github.com/hashicorp/terraform-plugin-docs v0.14.1/go.mod h1:k2NW8+t113jAus6bb5tQYQgEAX/KueE/u8X2Z45V1GM= github.com/hashicorp/terraform-plugin-framework v1.1.1 h1:PbnEKHsIU8KTTzoztHQGgjZUWx7Kk8uGtpGMMc1p+oI= github.com/hashicorp/terraform-plugin-framework v1.1.1/go.mod h1:DyZPxQA+4OKK5ELxFIIcqggcszqdWWUpTLPHAhS/tkY= github.com/hashicorp/terraform-plugin-go v0.14.0 h1:ttnSlS8bz3ZPYbMb84DpcPhY4F5DsQtcAS7cHo8uvP4= @@ -316,12 +320,16 @@ github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcncea github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= github.com/mitchellh/cli v1.1.5 h1:OxRIeJXpAMztws/XHlN2vu6imG5Dpq+j61AzAX5fLng= @@ -368,6 +376,7 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -401,8 +410,12 @@ github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaU github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U= github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -419,6 +432,8 @@ github.com/zclconf/go-cty v1.11.0 h1:726SxLdi2SDnjY+BStqB9J1hNp4+2WlzyXLuimibIe0 github.com/zclconf/go-cty v1.11.0/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA= github.com/zclconf/go-cty v1.12.1 h1:PcupnljUm9EIvbgSHQnHhUr3fO6oFmkOrvs2BAFNXXY= github.com/zclconf/go-cty v1.12.1/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA= +github.com/zclconf/go-cty v1.13.0 h1:It5dfKTTZHe9aeppbNOda3mN7Ag7sg6QkBNm6TkyFa0= +github.com/zclconf/go-cty v1.13.0/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= github.com/zclconf/go-cty-yaml v1.0.2 h1:dNyg4QLTrv2IfJpm7Wtxi55ed5gLGOlPrZ6kMd51hY0= github.com/zclconf/go-cty-yaml v1.0.2/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0= @@ -580,6 +595,7 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b h1:2n253B2r0pYSmEV+UNCQoPfU/FiaizQEK5Gu4Bq4JE8= golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/main.go b/main.go index a1631cf..828447c 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,9 @@ import ( "terraform-provider-stackoverflow/stackoverflow" ) +// Generate the Terraform provider documentation using `tfplugindocs`: +//go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs + func main() { plugin.Serve(&plugin.ServeOpts{ ProviderFunc: func() *schema.Provider { diff --git a/stackoverflow/data_answer.go b/stackoverflow/data_answer.go index 028a885..0cd6317 100644 --- a/stackoverflow/data_answer.go +++ b/stackoverflow/data_answer.go @@ -16,12 +16,14 @@ func dataAnswer() *schema.Resource { ReadContext: dataAnswerRead, Schema: map[string]*schema.Schema{ "answer_id": { - Type: schema.TypeInt, - Required: true, + Type: schema.TypeInt, + Required: true, + Description: "The identifier for the answer", }, "filter": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Description: "The API filter to use", }, }, } diff --git a/stackoverflow/data_article.go b/stackoverflow/data_article.go index cde45b4..06ca1d9 100644 --- a/stackoverflow/data_article.go +++ b/stackoverflow/data_article.go @@ -16,12 +16,14 @@ func dataArticle() *schema.Resource { ReadContext: dataArticleRead, Schema: map[string]*schema.Schema{ "article_id": { - Type: schema.TypeInt, - Required: true, + Type: schema.TypeInt, + Required: true, + Description: "The identifier for the article", }, "filter": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Description: "The API filter to use", }, }, } diff --git a/stackoverflow/data_filter.go b/stackoverflow/data_filter.go index 9afc99d..85131ae 100644 --- a/stackoverflow/data_filter.go +++ b/stackoverflow/data_filter.go @@ -15,8 +15,9 @@ func dataFilter() *schema.Resource { ReadContext: dataFilterRead, Schema: map[string]*schema.Schema{ "filter": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Description: "The identifier for the filter", }, }, } diff --git a/stackoverflow/data_question.go b/stackoverflow/data_question.go index fdbc1dd..2d634ce 100644 --- a/stackoverflow/data_question.go +++ b/stackoverflow/data_question.go @@ -16,12 +16,14 @@ func dataQuestion() *schema.Resource { ReadContext: dataQuestionRead, Schema: map[string]*schema.Schema{ "filter": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Description: "The API filter to use", }, "question_id": { - Type: schema.TypeInt, - Required: true, + Type: schema.TypeInt, + Required: true, + Description: "The identifier for the question", }, }, } diff --git a/stackoverflow/provider.go b/stackoverflow/provider.go index 1a843b1..c9ef99a 100644 --- a/stackoverflow/provider.go +++ b/stackoverflow/provider.go @@ -33,8 +33,9 @@ func Provider() *schema.Provider { Default: "https://api.stackoverflowteams.com/2.3/", }, "default_tags": { - Type: schema.TypeList, - Optional: true, + Type: schema.TypeList, + Optional: true, + Description: "A list of tags to automatically associate with any resources that support tags", Elem: &schema.Schema{ Type: schema.TypeString, }, diff --git a/stackoverflow/resource_answer.go b/stackoverflow/resource_answer.go index 2f120db..97d5f23 100644 --- a/stackoverflow/resource_answer.go +++ b/stackoverflow/resource_answer.go @@ -19,16 +19,19 @@ func resourceAnswer() *schema.Resource { DeleteContext: resourceAnswerDelete, Schema: map[string]*schema.Schema{ "body_markdown": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Description: "The answer content in Markdown format", }, "filter": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Description: "The API filter to use", }, "question_id": { - Type: schema.TypeInt, - Required: true, + Type: schema.TypeInt, + Required: true, + Description: "The question identifier that this answer applies to", }, }, Importer: &schema.ResourceImporter{ diff --git a/stackoverflow/resource_article.go b/stackoverflow/resource_article.go index 338f16f..46ad3cd 100644 --- a/stackoverflow/resource_article.go +++ b/stackoverflow/resource_article.go @@ -7,6 +7,7 @@ import ( so "terraform-provider-stackoverflow/stackoverflow/client" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -19,17 +20,21 @@ func resourceArticle() *schema.Resource { DeleteContext: resourceArticleDelete, Schema: map[string]*schema.Schema{ "article_type": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Description: "The type of article. Must be one of `knowledge-article`, `announcement`, `how-to-guide`, `policy`", + ValidateFunc: schema.SchemaValidateFunc(validation.StringInSlice([]string{"knowledge-article", "announcement", "how-to-guide", "policy"}, false)), }, "body_markdown": { - Type: schema.TypeString, - Optional: true, - Default: "", + Type: schema.TypeString, + Optional: true, + Default: "", + Description: "The article content in Markdown format", }, "filter": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Description: "The API filter to use", }, "tags": { Type: schema.TypeList, @@ -37,10 +42,12 @@ func resourceArticle() *schema.Resource { Elem: &schema.Schema{ Type: schema.TypeString, }, + Description: "The set of tags to be associated with the article", }, "title": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Description: "The title of the article", }, }, Importer: &schema.ResourceImporter{ diff --git a/stackoverflow/resource_question.go b/stackoverflow/resource_question.go index be5f5a2..89195d7 100644 --- a/stackoverflow/resource_question.go +++ b/stackoverflow/resource_question.go @@ -19,12 +19,14 @@ func resourceQuestion() *schema.Resource { DeleteContext: resourceQuestionDelete, Schema: map[string]*schema.Schema{ "body_markdown": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Description: "The question content in Markdown format", }, "filter": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Description: "The API filter to use", }, "tags": { Type: schema.TypeList, @@ -32,10 +34,12 @@ func resourceQuestion() *schema.Resource { Elem: &schema.Schema{ Type: schema.TypeString, }, + Description: "The set of tags to be associated with the article", }, "title": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Description: "The title of the article", }, }, Importer: &schema.ResourceImporter{ diff --git a/terraform-registry-manifest.json b/terraform-registry-manifest.json new file mode 100644 index 0000000..a8286e3 --- /dev/null +++ b/terraform-registry-manifest.json @@ -0,0 +1,6 @@ +{ + "version": 1, + "metadata": { + "protocol_versions": ["5.0"] + } +} \ No newline at end of file diff --git a/tools/tools.go b/tools/tools.go new file mode 100644 index 0000000..2844b66 --- /dev/null +++ b/tools/tools.go @@ -0,0 +1,8 @@ +//go:build tools + +package tools + +import ( + // document generation + _ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs" +)