Skip to content

feat: add archive_path attribute to coderd_template versions#344

Open
jatcod3r wants to merge 10 commits into
coder:mainfrom
jatcod3r:add-archive-path
Open

feat: add archive_path attribute to coderd_template versions#344
jatcod3r wants to merge 10 commits into
coder:mainfrom
jatcod3r:add-archive-path

Conversation

@jatcod3r
Copy link
Copy Markdown

@jatcod3r jatcod3r commented May 3, 2026

Implements #340. Adds archive_path as an alternative to directory in the versions block of coderd_template, supporting .tar and .zip files.

Changes:

  • Add archive_path (Optional) and archive_hash (Computed) attributes
  • Validator ensures exactly one of directory/archive_path is set
  • Plan modifier computes archive_hash from file contents (SHA-256)
  • normalizeZip adds missing directory entries for archives produced by Terraform's archive_file data source
  • uploadArchive sends the archive to Coder with correct content type
  • Warn when switching between archive_path and directory about hidden file inclusion differences
  • Document 100 MiB server upload limit in archive_path description

Tests:

  • TestComputeArchiveHash (4 cases)
  • TestArchiveContentType (5 cases)
  • TestNormalizeZip (2 cases)
  • TestReconcileVersionIDs extended with ArchiveHashMatching/Changed

@jatcod3r jatcod3r self-assigned this May 3, 2026
@jatcod3r jatcod3r force-pushed the add-archive-path branch from 7824c8c to 1f8930d Compare May 3, 2026 23:00
@ethanndickson ethanndickson self-requested a review May 7, 2026 02:53
@ethanndickson
Copy link
Copy Markdown
Member

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1f8930debf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/provider/template_resource.go Outdated
@jatcod3r
Copy link
Copy Markdown
Author

jatcod3r commented May 7, 2026

@codex review

@coder coder deleted a comment from chatgpt-codex-connector Bot May 7, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a48a37f432

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/provider/template_resource.go
Comment thread internal/provider/template_resource.go Outdated
@jatcod3r
Copy link
Copy Markdown
Author

jatcod3r commented May 7, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown
Member

@ethanndickson ethanndickson May 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a new subtest to TestAccTemplateResource that tests this feature works with a real coderd, if possible.

},
"archive_path": schema.StringAttribute{
Optional: true,
MarkdownDescription: "A path to a `.tar` or `.zip` archive file to upload as the template version source. Mutually exclusive with `directory`. Changes in the archive contents will trigger the creation of a new template version. The archive must not exceed 100 MiB (the Coder server upload limit).",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably validate the 100 MiB limit locally?

Comment thread internal/provider/template_resource.go Outdated
}

// normalizeZip rewrites a zip archive to ensure that all intermediate directory
// entries exist. Some tools (e.g. Terraform's archive_file data source) produce
Copy link
Copy Markdown
Member

@ethanndickson ethanndickson May 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the edge case archive_File presents us, maybe we need an end-to-end test too that uses that? We have an integration test harness for the provider that should support running this sort of test. If it's a pain to do an acceptance test, like the one I mentioned in my other comment (I don't recall how easy it is), just an integration test would be fine.

"directory_hash": schema.StringAttribute{
Computed: true,
},
"archive_path": schema.StringAttribute{
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neither me nor my agent can figure out why your agent used a new attribute here. Any ideas? Why couldn't we just use directory_hash? You could rename it but then you'd need a state migration, but it's not an attribute users would ever be concerned about so I think keeping it as directory_hash for both is fine?

Copy link
Copy Markdown
Author

@jatcod3r jatcod3r May 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to highlight archive_hash? Cause I agree, we could re-use directory_hash. Figured that I could detect changes based off the archive separately, but thinking about it now, we're really only worried about file content changes. Making that change now.

If you did mean archive_path, then I'm using that for targeting an individual archive file rather than a directory since that doesn't optionally cover standalone files. Unless u think we could modify it to encapsulate standalone archives too?

@jatcod3r jatcod3r force-pushed the add-archive-path branch from bb6aabd to 232f639 Compare May 13, 2026 18:02
@jatcod3r
Copy link
Copy Markdown
Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2da00fc7e4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/provider/template_resource.go
Implements coder#340. Adds archive_path as an alternative to directory in the
versions block of coderd_template, supporting .tar and .zip files.

Changes:
- Add archive_path (Optional) and archive_hash (Computed) attributes
- Validator ensures exactly one of directory/archive_path is set
- Plan modifier computes archive_hash from file contents (SHA-256)
- normalizeZip adds missing directory entries for archives produced by
  Terraform's archive_file data source
- uploadArchive sends the archive to Coder with correct content type
- Warn when switching between archive_path and directory about hidden
  file inclusion differences
- Document 100 MiB server upload limit in archive_path description

Tests:
- TestComputeArchiveHash (4 cases)
- TestArchiveContentType (5 cases)
- TestNormalizeZip (2 cases)
- TestReconcileVersionIDs extended with ArchiveHashMatching/Changed
Per Terraform framework guidance, validators should not emit errors for
unknown values. When either directory or archive_path is unknown (e.g.,
referencing a computed value from another resource), the XOR check is
skipped. Terraform will re-run validators once values resolve during
apply.
- Use stdpath.Dir (stdlib path package) instead of filepath.Dir when
  traversing ZIP entry names. ZIP entries always use forward slashes per
  spec, and filepath.Dir is OS-specific (would produce backslashes on
  Windows).

- Enhance the directory-to-archive_path switch warning to also mention
  that automatic tfvars file discovery is not performed for archive
  uploads, directing users to use tf_vars explicitly.
- Remove archive_hash attribute entirely
- Store archive file hash in directory_hash (same as directory hashing)
- Simplify contentHash() to only check directory_hash
- Both directory and archive uploads now use directory_hash for change
  detection, which stores the hash of the actual content (not archive
  metadata)

This unifies hash tracking regardless of source type, making the change
detection logic simpler and ensuring the hash represents actual template
content for both sources.
Validate that uploaded archives do not exceed the 100 MiB server limit
before attempting to upload. This provides faster feedback to users with
oversized archives and prevents server-side upload failures.
… entries

The Coder server's upload handler (coderd/files.go) converts uploaded ZIPs
to tar via archive.CreateTarFromZip(), and the tar extractor (provisionersdk.Untar)
calls os.MkdirAll(filepath.Dir(target)) for each file entry, creating parent
directories automatically. There is no requirement for explicit directory entries
in the uploaded ZIP.
@jatcod3r jatcod3r force-pushed the add-archive-path branch from b6caa7f to d014249 Compare May 13, 2026 22:18
…when unknown

- Removed contentHash() helper; inline DirectoryHash.ValueString() at call sites
- Replace empty-string fallback with actual hash computation in Create/Update
  when DirectoryHash is unknown (source path depended on another resource at
  plan time)
- Remove stale archive_hash comments
@jatcod3r
Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@jatcod3r jatcod3r linked an issue May 15, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(coderd_template): Support also referencing an archive file.

3 participants