-
Notifications
You must be signed in to change notification settings - Fork 4
Copy docs workflow #404
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
RubenSandwich
wants to merge
68
commits into
develop
Choose a base branch
from
rn/add-copy-docs-workflow
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+136,248
−17
Open
Copy docs workflow #404
Changes from all commits
Commits
Show all changes
68 commits
Select commit
Hold shift + click to select a range
b172f2d
Add enough for barebones test
RubenSandwich 342b4a6
Add push for testing
RubenSandwich 60eb367
Fix workflow name
RubenSandwich 12b0dc6
Add test file at root to check that PR opens
RubenSandwich c2e3369
login with github token
RubenSandwich 4b56c79
Update gh token
RubenSandwich ec30b5c
Try just a git push
RubenSandwich 102fcd7
Add back push head
RubenSandwich a6d16ef
merge into develop for now
RubenSandwich bcdc2bc
Remove push action
RubenSandwich 27d44ff
remove comment that was messing up code
RubenSandwich 67aa011
Get copy-cloud-docs-for-tfe compiling
RubenSandwich b84e5a6
Merge branch 'develop' into rn/add-copy-docs-workflow
RubenSandwich 813da4b
Only building only version metadata
RubenSandwich 4328005
Refactor to remove targetRepoLastSyncFile
RubenSandwich c0dc4e3
Downgrade remark to fix mdx v2 errors
RubenSandwich 8439ce2
Get Copy cloud-docs for TFE working
RubenSandwich ac124bf
Check if the branch name already exists
RubenSandwich b9991dd
Fix type errors
RubenSandwich 503dea9
Update the README with the new name
RubenSandwich 5abeeed
Test the whole workflow connected together
RubenSandwich 4c1a475
checkout the proper workflow file before running
RubenSandwich d51ac06
path should be a string
RubenSandwich d6a4a87
forgot a period
RubenSandwich e4af74d
Use latest sha for GHA run
RubenSandwich 25db2b1
Forgot to build :facepalm:
RubenSandwich 4b65042
double check that the checkout is working
RubenSandwich 4b93b64
Add the current loc to checkout
RubenSandwich 6f4f716
try the path just "testing"
RubenSandwich f5fdcc3
include the github workspace
RubenSandwich 1d0c631
It's github.workspace
RubenSandwich a64e2f2
checkout is deleting previous folder contents
RubenSandwich 1eab0df
Double check that the files are being moved over
RubenSandwich 7cda500
fix move command
RubenSandwich 631f326
fix a space in path
RubenSandwich 444c6c9
list files for debugging
RubenSandwich ef17d02
What is in our base dir
RubenSandwich 94742a5
copy dot files
RubenSandwich 30c6d67
correct file path
RubenSandwich 045bac1
For demo only add changed files in /ptfe-releases
RubenSandwich f3df9dc
For the sake of the demo do a clean PR
RubenSandwich 065e93f
Forgot to rebuild
RubenSandwich c55547f
base against develop
RubenSandwich 7f856a1
new-pr checkout should be develop as well
RubenSandwich 34d2145
clean up testing code
RubenSandwich 084ddd6
Don't copy over /architectural-details
RubenSandwich ee0677a
Corrected new-pr path
RubenSandwich 5388e7f
prebuild-only-version-metadata exists in branch
RubenSandwich 86c1f39
Correctly fetch the origin branch
RubenSandwich 0ea700d
use working-directory
RubenSandwich f2edb3e
Rewrite to support two different PRs
RubenSandwich f06f4ad
Resolve the versionMetadataPath
RubenSandwich 5b36f28
Fix working dir and branch checking code
RubenSandwich 3c5a97a
Remove branch checking code
RubenSandwich 86431ab
Try a new way to check for a branch existing
RubenSandwich 3914828
try again for branch checking
RubenSandwich 0b242e6
should be a "do not equals"
RubenSandwich ad5a48e
Update bot user
RubenSandwich fc945cc
Add diff PR to workflow
RubenSandwich 2563a92
Update PR names
RubenSandwich 8368498
Update a bit of the wording
RubenSandwich 32b959a
Remove testing code
RubenSandwich 701ffc4
Trigger copy docs from release notes workflow
RubenSandwich 5779835
delete old tests as they are no longer being used
RubenSandwich fee1ee1
Add copywrite headers
RubenSandwich d31ca4f
Merge branch 'develop' into rn/add-copy-docs-workflow
RubenSandwich 066c22c
Add todos to workflow
RubenSandwich 5bab866
Add parenthesis around closed message
RubenSandwich File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# `copy-cloud-docs-for-tfe` | ||
|
||
This composite action is consumed by the `copy-docs.yml` workflow, which is triggered | ||
at the time of the Terraform Enterprise team's **APP_DEADLINE** event. | ||
|
||
Roughly, it behaves as depicted in this diagram: | ||
|
||
```mermaid | ||
graph LR | ||
A[terraform-docs-common] -->|copy `/cloud-docs/*` contents<br/>alongside `/enterprise/*` contents| B[ptfe-releases] | ||
``` | ||
|
||
## Overview | ||
|
||
This action looks for a few things in authored `mdx`, to determine | ||
if sections or entire pages should be ignored from this copy process. | ||
|
||
### Frontmatter | ||
|
||
Adding a `tfc_only: true` line in markdown frontmatter signals to | ||
the action that the associated `.mdx` file should not be handled in the copy process. | ||
|
||
#### Example | ||
|
||
```markdown | ||
--- | ||
page_title: Assessments - API Docs - Terraform Cloud | ||
tfc_only: true | ||
description: >- | ||
Assessment results contain information about continuous validation in | ||
Terraform Cloud, like drift detection. | ||
--- | ||
``` | ||
|
||
### HTML Comments | ||
|
||
Specially formatted HTML comments can be used in matching pairs | ||
to omit multiple **lines** of text from the copy process. | ||
|
||
> **Warning**: This only works with MDX v1. | ||
|
||
#### Example | ||
|
||
```markdown | ||
Some content available in both TFC & TFE... | ||
|
||
<!-- BEGIN: TFC:only --> | ||
## Some section | ||
|
||
This will only be visible in TFC | ||
|
||
<!-- END: TFC:only --> | ||
|
||
More content available in both TFC & TFE... | ||
``` | ||
|
||
> **Note**: More details are available in this [TFC/TFE Content exclusion][rfc] RFC. | ||
|
||
[rfc]: https://docs.google.com/document/d/1DPJU6_7AdGIJVlwJUWBlRqREmYon2IgYf_DrtKjhkcE/edit |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Copyright (c) HashiCorp, Inc. | ||
# SPDX-License-Identifier: BUSL-1.1 | ||
|
||
name: Copy cloud-docs for TFE | ||
description: Copy docs/nav-data/assets from source dir to target dir | ||
runs: | ||
using: 'node20' | ||
main: 'out/index.js' | ||
inputs: | ||
source_path: | ||
required: true | ||
description: 'The path to source HCP terraform files from' | ||
target_path: | ||
required: true | ||
description: 'The path to copy over HCP terraform files to' | ||
new_TFE_version: | ||
required: false | ||
description: 'The new TFE version to create and copy docs into.' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/** | ||
* Copyright (c) HashiCorp, Inc. | ||
* SPDX-License-Identifier: BUSL-1.1 | ||
*/ | ||
|
||
import * as core from '@actions/core' | ||
|
||
import { main } from './main' | ||
|
||
async function action() { | ||
const sourcePath = core.getInput('source_path') | ||
const targetPath = core.getInput('target_path') | ||
const newTFEVersion = core.getInput('new_TFE_version') | ||
// const newTFEVersion = 'v000011-1' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comment can be removed |
||
|
||
await main(sourcePath, targetPath, newTFEVersion) | ||
} | ||
|
||
action() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,277 @@ | ||
/** | ||
* Copyright (c) HashiCorp, Inc. | ||
* SPDX-License-Identifier: BUSL-1.1 | ||
*/ | ||
|
||
import * as fs from 'fs' | ||
import * as path from 'path' | ||
|
||
import * as core from '@actions/core' | ||
import walk from 'klaw-sync' | ||
import matter from 'gray-matter' | ||
import remark from 'remark' | ||
import remarkMdx from 'remark-mdx' | ||
|
||
import { remarkGetImages } from './remark-get-images-plugin' | ||
import { remarkTransformCloudDocsLinks } from './remark-transfrom-cloud-docs-links' | ||
|
||
const PR_TYPE = { | ||
NewVersion: 'NewVersion', | ||
Diff: 'Diff', | ||
} as const | ||
|
||
const imageSrcSet = new Set<string>() | ||
|
||
// List of MDX files to exclude from being copied | ||
const IGNORE_LIST = ['cloud-docs/index.mdx'] | ||
|
||
export const IGNORE_PATTERNS: RegExp[] = [ | ||
/cloud-docs\/agents/i, | ||
/cloud-docs\/architectural-details/i, | ||
] | ||
const SUB_PATH_MAPPINGS: { | ||
source: string | ||
target: string | ||
}[] = [ | ||
{ | ||
source: 'cloud-docs', | ||
target: 'enterprise', | ||
}, | ||
] | ||
|
||
/** | ||
* This is a helper to be passed to `walk` dry up repeated logic | ||
* for ignore certain files. | ||
*/ | ||
const filterFunc = (item: walk.Item) => { | ||
// if the item matches a IGNORE_PATTERNS expression, exclude it | ||
if ( | ||
IGNORE_PATTERNS.some((pattern: RegExp) => { | ||
return pattern.test(item.path) | ||
}) | ||
) { | ||
return false | ||
} | ||
|
||
// Check files for `tfc_only` frontmatter property; Ignore them if true | ||
if (item.stats.isFile()) { | ||
const fullContent = fs.readFileSync(item.path, 'utf8') | ||
const { data } = matter(fullContent) | ||
if (data.tfc_only == true) { | ||
return false | ||
} | ||
} | ||
|
||
return true | ||
} | ||
|
||
/** | ||
* A helper that accepts a data object and an array of functions that | ||
* receive the object as an arg and transform it. | ||
*/ | ||
const transformObject = <T = Record<string, any>>( | ||
data: T, | ||
plugins: Array<(data: T) => T>, | ||
): T => { | ||
let result = data | ||
|
||
plugins.forEach((fn: (data: T) => T) => { | ||
result = fn(result) | ||
}) | ||
|
||
return result | ||
} | ||
|
||
/** | ||
* This function will copy 3 things | ||
* - MDX files | ||
* - these can be at varying levels of nesting | ||
* - used images | ||
* - these are expected to all be at the same level | ||
* - nav-data JSON files | ||
* | ||
* This function will also prune the target directory | ||
* of any files that are not in the source directory. | ||
* | ||
* @param newTFEVersion An absolute path to a GitHub repository on disk | ||
*/ | ||
export async function main( | ||
sourcePath: string, | ||
targetPath: string, | ||
newTFEVersion?: string, | ||
): Promise<void> { | ||
const prType = newTFEVersion ? PR_TYPE.NewVersion : PR_TYPE.Diff | ||
|
||
//Read version metadata and get the latest version of ptfe-releases | ||
const versionMetadataPath = path.resolve( | ||
'./workflow/app/api/versionMetadata.json', | ||
) | ||
const versionMetadata = JSON.parse( | ||
fs.readFileSync(versionMetadataPath, 'utf8'), | ||
) | ||
|
||
const ptfeReleasesMetadata = versionMetadata['ptfe-releases'] | ||
if (!ptfeReleasesMetadata || ptfeReleasesMetadata.length === 0) { | ||
throw new Error('No ptfe-releases found in versionMetadata.json') | ||
} | ||
|
||
const currentPtfeRelease = ptfeReleasesMetadata.find((release: any) => { | ||
return release.isLatest | ||
})?.version | ||
|
||
if (!currentPtfeRelease) { | ||
throw new Error('No latest ptfe-releases found in versionMetadata.json') | ||
} | ||
|
||
core.info( | ||
`Latest ptfe-releases version found in versionMetadata.json: ${currentPtfeRelease}`, | ||
) | ||
|
||
const HCPsourceDir = path.join(sourcePath, 'content/terraform-docs-common') | ||
const HCPContentDir = path.join(HCPsourceDir, 'docs') | ||
|
||
const newTFEVersionDir = path.join( | ||
targetPath, | ||
'content/ptfe-releases', | ||
prType === PR_TYPE.NewVersion ? newTFEVersion : currentPtfeRelease, | ||
) | ||
|
||
const newTFEVersionContentDir = path.join(newTFEVersionDir, 'docs') | ||
const newTFEVersionImageDir = path.join(newTFEVersionDir, 'img/docs') | ||
|
||
// If this is a new version, we need to copy the current ptfe-release | ||
// files to the new version's directory. | ||
// This is to ensure that we have the all of the images and nav-data | ||
if (prType === PR_TYPE.NewVersion) { | ||
core.info(`Creating new version directory: ${newTFEVersionDir}`) | ||
fs.mkdirSync(newTFEVersionDir, { recursive: true }) | ||
|
||
const prevTFEVersionDir = path.join( | ||
targetPath, | ||
'content/ptfe-releases', | ||
currentPtfeRelease, | ||
) | ||
|
||
fs.cpSync(prevTFEVersionDir, newTFEVersionDir, { recursive: true }) | ||
} | ||
|
||
// traverse source docs and accumulate mdx files for a given set of "subPaths" | ||
let items: ReadonlyArray<walk.Item> = [] | ||
|
||
for (const { source: subPath } of SUB_PATH_MAPPINGS) { | ||
const src = path.join(HCPContentDir, subPath) | ||
const docItems = walk(src, { | ||
nodir: true, | ||
filter: filterFunc, | ||
}) | ||
items = items.concat(docItems) | ||
} | ||
|
||
// process each mdx file | ||
for (const item of items) { | ||
// ignore some files | ||
if ( | ||
IGNORE_LIST.some((ignore: string) => { | ||
return item.path.endsWith(ignore) | ||
}) | ||
) { | ||
continue | ||
} | ||
|
||
// extract mdx content; ignore frontmatter | ||
const fullContent = fs.readFileSync(item.path, 'utf8') | ||
|
||
// eslint-disable-next-line prefer-const | ||
let { content, data } = matter(fullContent) | ||
|
||
data = transformObject(data, [ | ||
// inject `source` frontmatter property | ||
function injectSource(d: { [key: string]: any }) { | ||
d.source = path.basename(HCPsourceDir) | ||
return d | ||
}, | ||
// replace cloud instances with enterprise | ||
function replaceCloudWithEnterprise(d: { [key: string]: any }) { | ||
// Some docs do not have all frontmatter properties. Make sure | ||
// we do not assign `undefined` (which is invalid) in YAML | ||
if (d.page_title) { | ||
d.page_title = d.page_title.replace( | ||
'Terraform Cloud', | ||
'Terraform Enterprise', | ||
) | ||
d.page_title = d.page_title.replace( | ||
'HCP Terraform', | ||
'Terraform Enterprise', | ||
) | ||
} | ||
|
||
if (d.description) { | ||
d.description = d.description.replace( | ||
'Terraform Cloud', | ||
'Terraform Enterprise', | ||
) | ||
d.description = d.description.replace( | ||
'HCP Terraform', | ||
'Terraform Enterprise', | ||
) | ||
} | ||
return d | ||
}, | ||
]) | ||
|
||
const vfile = await remark() | ||
.use(remarkMdx) | ||
// @ts-expect-error remark is being passed in through the pipeline | ||
.use(remarkGetImages, HCPsourceDir, imageSrcSet) | ||
// @ts-expect-error remark is being passed in through the pipeline | ||
.use(remarkTransformCloudDocsLinks) | ||
.process(content) | ||
|
||
// replace \-> with -> | ||
const stringOutput = vfile.toString().replaceAll('\\->', '->') | ||
|
||
// overwrite original file with transformed content | ||
const contents = matter.stringify('\n' + stringOutput, data) | ||
fs.writeFileSync(item.path, contents) | ||
} | ||
|
||
// Copy an entire directory | ||
// --------------------------------------------- | ||
// /{source}/cloud-docs/dir/some-doc.mdx | ||
// ↓ ↓ ↓ ↓ | ||
// /{target}/enterprise/dir/some-docs.mdx | ||
// --------------------------------------------- | ||
for (const { source, target } of SUB_PATH_MAPPINGS) { | ||
const src = path.join(HCPContentDir, source) | ||
const dest = path.join(newTFEVersionContentDir, target) | ||
|
||
const items = walk(src, { | ||
nodir: true, | ||
filter: filterFunc, | ||
}) | ||
|
||
for (const item of items) { | ||
// ignore some files | ||
if ( | ||
IGNORE_LIST.some((ignore: string) => { | ||
return item.path.endsWith(ignore) | ||
}) | ||
) { | ||
continue | ||
} | ||
|
||
const destAbsolutePath = item.path.replace(src, dest) | ||
fs.mkdirSync(path.dirname(destAbsolutePath), { recursive: true }) | ||
fs.copyFileSync(item.path, destAbsolutePath) | ||
} | ||
} | ||
|
||
// Copy images | ||
for (const src of Array.from(imageSrcSet)) { | ||
const basename = path.basename(src) | ||
const target = path.join(newTFEVersionImageDir, basename) | ||
|
||
fs.mkdirSync(newTFEVersionImageDir, { recursive: true }) | ||
fs.copyFileSync(src, target) | ||
} | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
/cloud-docs/*
and/enterprise/*
are showing asUnsupported markdown
in the rich diff