Initial commit

This commit is contained in:
Christian Nunciato
2021-04-06 07:36:14 -07:00
parent 7e52132b30
commit fb56ee45f6
63 changed files with 11607 additions and 15 deletions
+29
View File
@@ -0,0 +1,29 @@
name: Close pull request
on:
pull_request:
types:
- closed
jobs:
cleanup:
# Only run this job for events that originate on this repository.
if: github.event.pull_request.head.repo.full_name == github.repository
name: Find and remove buckets
runs-on: ubuntu-18.04
steps:
- name: Check out branch
uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-west-2
role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }}
role-session-name: PullRequestCleanupSession
- name: Find and remove buckets
run: make ci-pull-request-closed
env:
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+45
View File
@@ -0,0 +1,45 @@
name: Pull request
on:
pull_request:
branches:
- master
jobs:
preview:
# Only run this job for events that originate on this repository.
if: github.event.pull_request.head.repo.full_name == github.repository
name: Build and deploy preview
runs-on: ubuntu-18.04
steps:
- name: Install Node
uses: actions/setup-node@v1
with:
node-version: '14.x'
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: 1.16.x
- name: Install Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: '0.81.0'
extended: true
- name: Check out branch
uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-west-2
role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }}
role-session-name: PullRequestPreviewSession
- name: Build and deploy preview
run: make ci-pull-request
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
+33
View File
@@ -0,0 +1,33 @@
name: Scheduled
on:
schedule:
# Daily at 3:00PM UTC
- cron: 0 15 * * *
jobs:
cleanup:
name: Find and remove buckets
runs-on: ubuntu-18.04
steps:
- name: Check out branch
uses: actions/checkout@v2
- name: Install Node
uses: actions/setup-node@v1
with:
node-version: '14.x'
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-west-2
role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }}
role-session-name: BucketCleanupSession
- name: Find and remove buckets
run: make ci-scheduled
env:
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
SLACK_ACCESS_TOKEN: ${{ secrets.SLACK_ACCESS_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+5
View File
@@ -0,0 +1,5 @@
_vendor
node_modules
resources
themes/*/resources
public
+1
View File
@@ -0,0 +1 @@
14
+193
View File
@@ -0,0 +1,193 @@
# Writing and Publishing a Pulumi Blog Post
So you're interested in contributing to the Pulumi blog? Great! Follow these
steps to make it happen.
## Set Up Your Development Environment
If you haven't already, clone this repository and
[follow the instructions in the README](https://github.com/pulumi/docs#pulumi-documentation-site)
to set up your environment and run the development web server.
Once you're able to run:
```zsh
make serve
```
If you can browse the site locally at http://localhost:1313/ then you are ready to
proceed to the next section.
## Make a New Post
1. Resist the temptation to copy-and-tweak an existing post! Instead, run the following
command into the terminal (at the root of the project). This will generate a new file,
including all the required frontmatter parameters.
```zsh
make new-blog-post
```
This will prompt you for a "slug" (a URL-friendly path) for your post and create a
minimal post that you can browse to at http://localhost:1313/blog/. You'll find the new
post's source file at `themes/default/content/blog/[your-slug]/_index.md` containing the set of
[Hugo front matter](https://gohugo.io/content-management/front-matter/) properties you'll need to get started:
```
---
title: "My New Post"
date: 2019-07-17T14:26:50-07:00
draft: true
meta_image: meta.png
authors:
- joe-duffy
tags:
- some-tag
---
```
Feel free to adjust the title, authors (more on this below) and tags as appropriate. To change the post's URL, simply rename the folder containing `_index.md`; changing the folder name to `my-awesome-post`, for example, would result in a post ultimately published at https://www.pulumi.com/blog/my-awesome-post.
**Important**
The `title` will populate the `<title>` tag of the page, the `<h1>`, and the display value if it is linked to internally. This field has a strict 60 character limit because of SEO related limitations. If you would like to have a longer display title (i.e. the `<h1>` tag) then you will need to specify it by adding `h1: Whatever title you would like` to the front matter. If you would like to display different text on internal links than what the `title` value is, you can also specify a `linktitle` value. Both the `h1` and `linktitle` values can be of any length. Below is an example of this:
```
---
title: This a Page Title
h1: This is the H1 for the page
linktitle: This is the link text
...
---
```
**Keep in mind that only posts dated prior to "now" (meaning the moment the build process begins) and _not_ marked as `draft`s will published to production.** The development server renders both future and draft content (so you can work on scheduled posts in advance), but the build process does not; see below for details on scheduling posts for future publishing.
2. If you don't already have a [TOML](https://github.com/toml-lang/toml) file [in the `team` directory](https://github.com/pulumi/docs/tree/master/data/team/team) of the repo, create one now. For Pulumi employees, that file should look something like this:
```
id = "christian-nunciato"
name = "Christian Nunciato"
title = "Software Engineer"
status = "active"
[social]
github = "cnunciato"
linkedin = "cnunciato"
twitter = "cnunciato"
```
For community contributors, it's mostly the same, but with a `status` of `guest`, and a more informative `title`:
```
id = "mikhail-shilkov"
name = "Mikhail Shilkov"
title = "Microsoft Azure MVP and early Pulumi user"
status = "guest"
...
```
The `social` section, and the items within it, are optional.
Once your team-member file's been created, update the new post's `authors` property to refer to your team member `id` string. If you're still running the development server, you should see the change reflected in the browser immediately.
## Write Your Post
Posts are written in [Markdown](https://daringfireball.net/projects/markdown/) and rendered with [BlackFriday](https://github.com/russross/blackfriday), Hugo's default Markdown processor. GitHub's [Mastering Markdown](https://guides.github.com/features/mastering-markdown/) guide is a helpful syntax reference if you need it. You can also include HTML in your posts, if you need greater control over the output than Markdown can provide.
For formatting guidelines, see the Style Guide in [CONTRIBUTING.md](CONTRIBUTING.md#style-guide).
### Code Blocks
There are a couple of ways to do [syntax highlighing](https://gohugo.io/content-management/syntax-highlighting/) in Hugo, but we generally recommend [code fences](https://gohugo.io/content-management/syntax-highlighting/#highlight-in-code-fences), along with an optional language specifier &mdash; e.g., for TypeScript:
<pre>
```typescript
let bucket = new aws.s3.Bucket("stuff");
...
```
</pre>
[Additional languages are available](https://gohugo.io/content-management/syntax-highlighting/#list-of-chroma-highlighting-languages) as well.
### Notes
Shortcode for a warning note:
```
{{% notes type="warning" %}}
**DANGER** Will Robinson!
{{% /notes %}}
```
Shortcode for an info note:
```
{{% notes type="info" %}}
Using Bastion hosts is a best practice.
{{% /notes %}}
```
### Media
#### Inline Images
To add images to the body of your post, first place them within in the folder containing the post's Markdown file (e.g., at `blog/my-new-post/platypus.png`), then reference them relatively:
```
![The humble platypus](platypus.png)
```
#### Social ("Meta") Images
When you generate a new post, an [OpenGraph](http://ogp.me/) placeholder image is included for you, and a reference to that image is added to the post's frontmatter as well, as its `meta_image`. The `meta_image` is meant to accompany the post in social previews (Twitter cards, unfurled Slack links, etc.) and on the Pulumi blog home page. It's optional, but recommended, as it can help to make your post more attractive and informative.
For best results, we suggest the following specs for the `meta_image`, largely based on [Twitter's dev docs](https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/abouts-cards):
| Aspect Ratio | Recommended Size | Format | Background |
| ------------ | ---------------- | ------ | ------------------------ |
| 2:1 | 1200×600 | PNG | Opaque (No Transparency) |
Remember to replace the `meta_image` placeholder (or remove the property altogether and delete the placeholder `meta.png` file) before submitting your post.
#### Video
To embed a YouTube video, you can use Hugo's built-in [`youtube` shortcode](https://gohugo.io/content-management/shortcodes/#youtube), which takes the video's YouTube ID, obtainable from its public URL on youtube.com:
```
{{< youtube "kDB-YRKFfYE?rel=0" >}}
```
For videos belonging to the [Pulumi YouTube channel](https://www.youtube.com/channel/UC2Dhyn4Ev52YSbcpfnfP0Mw), you'll usually want to append the `?rel=0` query parameter as well (as above), which tells YouTube to limit the suggestions it makes at the end of a video to those from the same YouTube channel. [Learn more about player parameters here](https://developers.google.com/youtube/player_parameters).
#### Tweets
There's a Hugo [shortcode for Tweets](https://gohugo.io/content-management/shortcodes/#tweet), too, which accepts a Tweet ID, accessible [from its permalink](https://twitter.com/jcreed/status/1147203941609984002):
```
{{< tweet 1147203941609984002 >}}
```
For more Hugo shortcode fun, [go here](https://gohugo.io/content-management/shortcodes).
## Done? Submit!
When you're ready to submit your post for review, issue a Pull Request against the `master` branch of the repo, and the team will have a look. Once merged &mdash; provided its `date` has passed and its `draft` status is no longer `true` &mdash; the post will be deployed to https://www.pulumi.com/.
## A Note on Dates and Scheduling for Future Publishing
If you'd like your post to be published at some future date or time, you have a couple of options.
Since the build process is triggered by (and so requires) a commit to `master`, you can either wait for the post's `date` to pass, remove its `draft` setting (or change it to `false`), and _then_ merge it, or leave its `draft` property `true`, merge, then change the property to `false` once the `date`'s gone by. If a post happens to get merged with `draft: false` and a future date, the resulting build will exclude the post, requiring a commit of some sort to occur _after_ its `date` in order to trigger a build and get the post published.
For this reason, leaving the `draft` property `true` until you're actually ready to publish gives you an easy way to kick off a build when the time comes.
## Publishing Check List
- [ ] As mentioned, use the Hugo blog-post generator instead of copying another post: `make new-blog-post` (or alternatively, the more verbose but equivalent `hugo new --kind blog-post "themes/default/content/blog/[your-slug]"`)
- [ ] Drafts will not be published, so either set `draft: false` or or delete it.
- [ ] Spell and grammar check. Consider using a service such as [Grammarly](http://grammarly.com).
- [ ] Check for a break `<!--more-->` after the first paragraph, and ensure that your post's introduction looks right on the blog home page.
- [ ] Check that your meta_image appears properly on the blog home page. Do not use animated GIFs for preview images.
- [ ] Preview locally. Check formatting, links, and images for appearance.
- [ ] Use the [Twitter card validator](https://cards-dev.twitter.com/validator) to check the how the blog appears in a tweet (use the preview provided in the PR).
+73
View File
@@ -0,0 +1,73 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
education, socio-economic status, nationality, personal appearance, race,
religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at code-of-conduct@pulumi.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
+86
View File
@@ -0,0 +1,86 @@
# Contributing Pulumi Documentation
## Pulumi terminology
- Use `pulumi` or "the Pulumi CLI" to refer to the CLI.
- Use `pulumi.com` to refer to the service.
## Documentation structure
- There is a folder for each heading in the top navigation, such as `Install`, `getting-started`, etc.
- The mapping from documentation page to section and table-of-contents (TOC) is stored largely in each page's front matter, leveraging [Hugo Menus](https://gohugo.io/content-management/menus/). Menus for the CLI commands and API reference are specified in `./config.toml`.
### Links to other files
We generally use Hugo's [`relref` shortcode](https://gohugo.io/content-management/shortcodes/#ref-and-relref) when linking to other pages. Examples:
```markdown
[Install]({{< relref "/docs/get-started/install" >}})
[Outputs]({{< relref "/docs/intro/concepts/stack#outputs" >}})
```
Which, on a page inside the `./content/reference` directory, will generate:
```html
<a href="/docs/install/">Install</a>
<a href="/docs/intro/concepts/stack/#stack-outputs">Outputs</a>
```
### Hugo tips
- **Redirects.** If you rename a file or directory, add a 301 redirect in the front-matter via an [alias](https://gohugo.io/content-management/urls/#aliases) `aliases: [/previous-dir/previousfile.html]`.
- **Includes.**
- **.md files.** To share common content across articles, use [Hugo Shortcodes](https://gohugo.io/content-management/shortcodes/). Place a .html file in the [layouts/shortcodes] folder. To include it in a page, use syntax `{{< my-shortcode >}}`
For example, our custom [`cleanup`](layouts/shortcodes/cleanup.html) shortcode can be included in .md files, to include common text about cleaning up stack resources:
```md
{{< cleanup >}}
```
- **.html layout files.** HTML layouts can include other layouts inside the [layouts/partials](layouts/partials) directory, e.g.:
```html
{{ partial "head.html" . }}
```
- **Front-matter variables.** You can define a front-matter variable in the YAML section at the top of a file. For instance, the you could add the following front matter `foo: "bar"`, and then reference the variable in markdown with the syntax `{{< param foo >}}`.
- **no_on_this_page** Specify this variable to prevent displaying an "On This Page" TOC on the right nav for the page.
- **block_external_search_index** Specify this variable to prevent crawlers from indexing the page.
## Style guide
### Language and terminology styles
- Top level headings use **Title Case**, where each word starts with a capital letter.
- All other headings use **Sentence case**, where only the first word and any proper nouns have a capital letter.
- Use capitalization only for a proper noun, and use throughout. For example, "stack" should almost always be lowercase in text.
### Referring to "things"
- References to the Pulumi CLI or CLI commands should be enclosed in backticks (e.g., `pulumi up`).
- References to UI elements within a webpage should be **bold**. (e.g., "Go to the **Account** page in the Pulumi Console and select **sync profile with GitHub**").
- Use arrows to indicate a navigation. (e.g., "Go to **FooPage** &gt; **BarItem**").
### Formatting
- Use hash marks for headings (`#`, `##`, etc)
- Use double-asterisks for bold `**`
- Use underscore for italic `_`
- Use `--` for en dashes and `---` for em dashes
- Do not put spaces before or after the dashes
- Use code fences (triple-backticks) and a [language identifier](https://gohugo.io/content-management/syntax-highlighting/) for code formatting and syntax highlighting:
<pre><code>```typescript
const foo = "bar";
```</code></pre>
### Sections
If a tutorial has more following tutorials, use a **Next steps** section at the end. If you're linking to other reference material, use **Learn more**.
## Blog Post Authoring
For instructions on contributing to the [Pulumi blog](https://www.pulumi.com/blog/), [see BLOGGING.md](BLOGGING.md).
+40
View File
@@ -0,0 +1,40 @@
.PHONY: clean
clean:
./scripts/clean.sh
.PHONY: ensure
ensure: clean
./scripts/ensure.sh
.PHONY: lint
lint:
./scripts/lint.sh
.PHONY: build
build:
./scripts/build.sh
.PHONY: serve
serve:
./scripts/serve.sh
.PHONY: serve-all
serve-all:
./scripts/serve.sh all
.PHONY: ci-pull-request
ci-pull-request: ensure
./scripts/ci/pull-request.sh
.PHONY: ci-pull-request-closed
ci-pull-request-closed:
./scripts/ci/pull-request-closed.sh
.PHONY: ci-scheduled
ci-scheduled:
./scripts/ci/scheduled.sh
.PHONY: new-blog-post
new-blog-post:
hugo new --kind blog-post \
"themes/default/content/blog/$(shell bash -c 'read -p "Slug (e.g., 'my-new-post'): " slug; echo $$slug')"
+104
View File
@@ -0,0 +1,104 @@
# pulumi-hugo
A [Hugo](https://gohugo.io) module containing the Pulumi Hugo theme and website content.
This repository is consumed by https://github.com/pulumi/docs to produce the website you see at https://pulumi.com. If you're interested in contributing some docs or a blog post at https://pulumi.com/blog, you've come to the right place! 🙌
## Contributing
First, be sure to read our [contributing guide](CONTRIBUTING.md) and review our [code of conduct](CODE_OF_CONDUCT.md).
## Toolchain
We build the Pulumi website statically with Hugo, manage our Node.js dependencies with Yarn, and write most of our documentation in Markdown. Below is a list of the tools you'll need to run the website locally:
* [Go](https://golang.org/)
* [Hugo](https://gohugo.io)
* [Node.js](https://nodejs.org/en/)
* [Yarn](https://classic.yarnpkg.com/en/)
### CSS and JavaScript Tools
We also use a handful of tools for compiling and managing our CSS and JavaScript assets, including:
* [Sass](https://sass-lang.com/)
* [TailwindCSS](https://tailwindcss.com/)
* [Stencil.js](https://stenciljs.com/)
* [TypeScript](https://www.typescriptlang.org/)
You don't need to install these tools individually or globally; the scripts below will handle everything for you. But if you'd like to contribute any CSS or JavaScript, you'll probably want to understand how to work with each of these tools as well.
## Installing prerequisites
Run `make ensure` to check for the appropriate tools and versions and install any dependencies. The script will let you know if you're missing anything important.
```
make ensure
```
## Running Hugo locally
Once you've run `make ensure` successfully, you're ready to run the development server. If you're only planning on writing Markdown or working with Hugo layouts, this command should be all you need:
```
make serve
```
You can browse the development server at http://localhost:1313, and any changes you make to content or layouts should be reloaded automatically.
## Running Hugo with CSS and JavaScript support
If you plan on making changes to CSS or JavaScript files, you'll probably want to use this command instead:
```
make serve-all
```
The `serve-all` target runs Hugo, node-sass, and the Stencil development server concurrently, allowing you to make changes to Sass files, Stencil components, or TypeScript/JavaScript source files, and have those changes compiled and reloaded automatically as well.
## Tidying up
To clear away any module caches or build artifacts, run:
```
make clean
```
## About this repository
This repository is a [Hugo module](https://gohugo.io/hugo-modules/) that doubles as a development server. **It does not contain every page of the Pulumi website**, because most of those pages (e.g., those comprising our CLI and SDK docs) are generated from source code, so they aren't meant to be edited by humans directly.
Because of this, many of the links you follow when browsing around on the development server (to paths underneath `/docs/reference` for example) will fail to resolve because their content files are are checked into a different repository &mdash; most likely https://github.com/pulumi/docs. When we build the Pulumi website, we merge this module along with any others into a single build artifact, but when you're working within an individual module like this one, you may find you're unable to reach certain pages or verify the links you may want to make to them.
If you want to link to a page that exists on https://pulumi.com but not in this repository, just use the page's **relative path** with a [Hugo `relref`](https://gohugo.io/content-management/shortcodes/#ref-and-relref) in the usual way, and we'll make sure all links resolve properly at build-time. For example, to link to the [Digital Ocean Droplet](https://www.pulumi.com/docs/reference/pkg/digitalocean/droplet/) page (a page that doesn't exist in this repository but that would exist in an integration build), you'd use:
```
{{< relref /docs/reference/pkg/digitalocean/droplet >}}
```
This works because we've suppressed Hugo's built-in `relref` validation to keep the module-development workflow as lightweight as possible.
### What's in this repo
* All hand-authored content and documentation, including top-level pages, guides, blog posts, and some tutorials
* Most Hugo module components, including archetypes, layouts, partials, shortcodes, data, etc.
You'll find all of these files in `themes/default`.
### What's not in this repo
* Generated documentation for the Pulumi CLI and SDK. You'll find this at https://github.com/pulumi/docs).
* Generated tutorials. You'll find these at https://github.com/pulumi/examples).
* Templates used for generating resource documentation. You'll find these at https://github.com/pulumi/pulumi.
## Merging and releasing
When a pull request is merged into the default branch of this repository, a follow-up PR is triggered on [pulumi/docs](https://github.com/pulumi/docs) that produces an integration build. Once that build completes and is approved and merged into pulumi/docs, the changes are deployed to pulumi.com.
## Blogging
Interested in writing a blog post? See the [blogging README](BLOGGING.md) for details.
## Shortcodes and web components
We use number of Hugo shortcodes and web components in our pages. You can read more about many of them in the [components README](themes/default/components).
+79
View File
@@ -0,0 +1,79 @@
languageCode: en-us
title: Pulumi - Modern Infrastructure as Code
theme: default
refLinksErrorLevel: WARNING
disableKinds:
- category
- taxonomyTerm
sectionPagesMenu: main
pygmentsCodeFences: true
pygmentsUseClasses: true
# We always generate the robots.txt file. But based on the environment
# built, it may disallow crawling.
enableRobotsTXT: true
# Enabling Git info allows us to have Hugo automatically set the lastmod date in sitemap
# XML with the date the file was last changed (according to Git).
enableGitInfo: true
# Some of our API docs pages are very large with many shortcodes, which can take
# a while to generate (especially in CI), so we raise the limit from the default
# 10 seconds to avoid timeouts when generating the site.
timeout: 300000
outputFormats:
rss:
baseName: rss
# We set the outputs explicitly to just "HTML" as otherwise they default to both
# "HTML" and "RSS", and we only want to generate RSS for the blog section -- not
# all sections/taxonomies. We enable RSS as an output for the blog section alone
# in the front matter of content/blog/_index.md and have a custom RSS template
# in layouts/blog/rss.xml.
outputs:
home:
- HTML
section:
- HTML
taxonomies:
author: authors
tag: tags
permalinks:
authors: /blog/author/:slug/
tags: /blog/tag/:slug/
markup:
goldmark:
extensions:
definitionList: true
footnote: true
linkify: true
strikethrough: true
table: true
taskList: true
typographer: true
parser:
autoHeadingID: true
autoHeadingIDType: "github"
attribute:
block: false
title: true
renderer:
hardWraps: false
unsafe: true
xhtml: false
params:
canonicalURL: https://www.pulumi.com
repositoryURL: https://github.com/pulumi/pulumi-hugo
repositoryBranch: master
meta_desc: |
Pulumi's open source infrastructure as code SDK enables you to create, deploy,
and manage infrastructure on any cloud, using your favorite languages.
+93
View File
@@ -0,0 +1,93 @@
# -------------------------------------
# Command Line Menu
# -------------------------------------
reference:
- name: cancel
parent: cli
url: /docs/reference/cli/pulumi_cancel/
weight: 1
- name: config
parent: cli
url: /docs/reference/cli/pulumi_config/
weight: 2
- name: console
parent: cli
url: /docs/reference/cli/pulumi_console/
weight: 3
- name: destroy
parent: cli
url: /docs/reference/cli/pulumi_destroy/
weight: 4
- name: import
parent: cli
url: /docs/reference/cli/pulumi_import/
weight: 5
- name: login
parent: cli
url: /docs/reference/cli/pulumi_login/
weight: 6
- name: logout
parent: cli
url: /docs/reference/cli/pulumi_logout/
weight: 7
- name: logs
parent: cli
url: /docs/reference/cli/pulumi_logs/
weight: 8
- name: new
parent: cli
url: /docs/reference/cli/pulumi_new/
weight: 9
- name: plugin
parent: cli
url: /docs/reference/cli/pulumi_plugin/
weight: 10
- name: policy
parent: cli
url: /docs/reference/cli/pulumi_policy/
weight: 11
- name: preview
parent: cli
url: /docs/reference/cli/pulumi_preview/
weight: 12
- name: refresh
parent: cli
url: /docs/reference/cli/pulumi_refresh/
weight: 13
- name: stack
parent: cli
url: /docs/reference/cli/pulumi_stack/
weight: 14
- name: state
parent: cli
url: /docs/reference/cli/pulumi_state/
weight: 15
- name: up
parent: cli
url: /docs/reference/cli/pulumi_up/
weight: 16
- name: version
parent: cli
url: /docs/reference/cli/pulumi_version/
weight: 17
- name: whoami
parent: cli
url: /docs/reference/cli/pulumi_whoami/
weight: 18
+3
View File
@@ -0,0 +1,3 @@
module github.com/pulumi/pulumi-hugo
go 1.16
+13
View File
@@ -0,0 +1,13 @@
{
"name": "pulumi-hugo",
"version": "0.0.1",
"private": true,
"repository": "git@github.com:pulumi/pulumi-hugo",
"author": "Christian Nunciato <c@nunciato.org>",
"license": "MIT",
"dependencies": {
"concurrently": "^6.0.0",
"js-yaml": "^3.13.1",
"markdownlint": "^0.17.2"
}
}
+9
View File
@@ -0,0 +1,9 @@
#!/bin/bash
set -o errexit -o pipefail
source ./scripts/common.sh
yarn --cwd themes/default run build
hugo | grep -v -e 'WARN .* REF_NOT_FOUND'
+29
View File
@@ -0,0 +1,29 @@
#!/bin/bash
set -o errexit -o pipefail
source ./scripts/ci/common.sh
# URL to the Pulumi conversion service.
export PULUMI_CONVERT_URL="${PULUMI_CONVERT_URL:-$(pulumi stack output --stack pulumi/tf2pulumi-service/production url)}"
printf "Compiling theme JavaScript and CSS...\n\n"
export ASSET_BUNDLE_ID="$(build_identifier)"
# Paths to the CSS and JS bundles we'll generate below. Note that environment variables
# are read by some templates during the Hugo build process.
export CSS_BUNDLE="static/css/styles.${ASSET_BUNDLE_ID}.css"
export JS_BUNDLE="static/js/bundle.min.${ASSET_BUNDLE_ID}.js"
# Relative paths to those same files, read by Hugo templates.
export REL_CSS_BUNDLE="/css/styles.${ASSET_BUNDLE_ID}.css"
export REL_JS_BUNDLE="/js/bundle.min.${ASSET_BUNDLE_ID}.js"
yarn --cwd themes/default run build
printf "Running Hugo...\n\n"
export REPO_THEME_PATH="themes/default/"
export HUGO_BASEURL="http://$(origin_bucket_prefix)-$(build_identifier).s3-website.$(aws_region).amazonaws.com"
hugo --minify --templateMetrics --buildDrafts --buildFuture -e "preview" | grep -v -e 'WARN .* REF_NOT_FOUND'
printf "Done!\n\n"
+156
View File
@@ -0,0 +1,156 @@
#!/bin/bash
repo_name() {
echo "pulumi-hugo"
}
aws_region() {
echo "us-west-2"
}
# Posts a message to Slack. Requires a valid access token is available in $SLACK_ACCESS_TOKEN.
# Usage: post_to_slack <channel> <message>
post_to_slack() {
local channel=$1
local message=$2
local escaped=$(echo ${message} | sed 's/"/\"/g' | sed "s/'/\'/g" )
local json="{\"channel\": \"#${channel}\", \"text\": \"${escaped}\", \"as_user\": true}"
curl -s \
-X POST \
-H "Content-type: application/json" \
-H "Authorization: Bearer ${SLACK_ACCESS_TOKEN}" \
-d "${json}" \
https://slack.com/api/chat.postMessage > /dev/null
}
# Posts a comment to a GitHub PR. Requires a GitHub token is available in $GITHUB_TOKEN.
# Usage: post_github_pr_comment "Hi!" "https://api.github.com/repos/<org>/<repo>/issues/<pr-number>/comments"
post_github_pr_comment() {
local pr_comment=$1
local pr_comment_api_url=$2
local pr_comment_body=$(printf '{ "body": "%s" }' "$pr_comment")
curl -s \
-X POST \
-H "Authorization: token ${GITHUB_TOKEN}" \
-d "$pr_comment_body" \
$pr_comment_api_url > /dev/null
}
# Returns the Git SHA of the HEAD commit. For pull requests, we take this from GitHub event metadata, since in that case, the HEAD commit will contain the SHA of the merge commit with the base branch.
git_sha() {
if [[ "$GITHUB_EVENT_NAME" == "pull_request" && ! -z "$GITHUB_EVENT_PATH" ]]; then
echo "$(cat "$GITHUB_EVENT_PATH" | jq -r ".pull_request.head.sha")"
else
echo "$(git rev-parse HEAD)"
fi
}
# Returns the shortened version of either the GITHUB_SHA, if present, or that of the most
# recent commit.
git_sha_short() {
echo "$(git_sha)" | cut -c1-8
}
# current_time_in_ms returns the epoch time in milliseconds.
current_time_in_ms() {
echo "$(node -e 'console.log(Date.now())')"
}
origin_bucket_prefix() {
echo "$(repo_name)-origin"
}
# Returns the name of the metadata file we expect to exist locally before running Pulumi.
origin_bucket_metadata_filepath() {
echo "./origin-bucket-metadata.json"
}
# build_identifier returns a string that is used to identify the current build for naming
# S3 buckets and asset bundles.
build_identifier() {
local identifier
# For CI builds, we use the GitHub Actions event to generate more readable identifiers.
# - For pull_request actions, return "pr-<number>-<git-sha>"
# - For others, return "<event-name>-<git-sha>".
if [[ ! -z "$GITHUB_EVENT_NAME" && ! -z "$GITHUB_EVENT_PATH" ]]; then
identifier="$GITHUB_EVENT_NAME"
if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then
identifier="pr-$(cat "$GITHUB_EVENT_PATH" | jq -r ".number")"
fi
identifier="${identifier}-$(git_sha_short)"
else
# For on-demand builds, if an identifier's been set, use it.
identifier="$BUILD_IDENTIFIER"
# Otherwise, just use the current Git SHA.
if [ -z "$BUILD_IDENTIFIER" ]; then
identifier="$(git_sha_short)"
fi
fi
echo "$identifier"
}
# Get the AWS SSM Parameter Store key for the specified commit SHA. Used for mapping a
# commit to a previously created bucket.
ssm_parameter_key_for_commit() {
echo "/$(repo_name)/commits/$1/bucket"
}
# Get the S3 bucket associated with a specific commit.
get_bucket_for_commit() {
aws ssm get-parameter \
--name "$(ssm_parameter_key_for_commit $1)" \
--query Parameter.Value \
--region us-west-2 \
--output text || echo ""
}
aws_owner_tag() {
echo "Key=Owner,Value=pulumi-hugo"
}
# Set the S3 bucket associated with a specific commit.
set_bucket_for_commit() {
aws ssm put-parameter \
--name "$(ssm_parameter_key_for_commit $1)" \
--value "$2" \
--type String \
--region $3 \
--tags "$(aws_owner_tag)"
}
# List the 100 most recent bucket in the current account, sorted descendingly by
# CreationDate, matching the prefix we use to name website buckets. Supports an optional
# suffix to filter by (e.g., "pr" or "push").
get_recent_buckets() {
aws s3api list-buckets \
--query "reverse(sort_by(Buckets,&CreationDate))[:100].{id:Name,date:CreationDate}|[?starts_with(id,'$(origin_bucket_prefix)-${1}')]" \
--output json | jq -r '.[].id'
}
# Retry the given command some number of times, with a delay of some number of seconds between calls.
# Usage: retry some_command <retry-count> <delay-in-seconds>
retry() {
local n=1
local max=$2
local delay=$3
while true; do
"$@" && break || {
if [[ $n -lt $max ]]; then
((n++))
echo "Command failed. Attempt $n/$max:"
sleep $delay;
else
echo "The command has failed after $n attempts." >&2
return 1
fi
}
done
}
+169
View File
@@ -0,0 +1,169 @@
#!/bin/bash
set -o errexit -o pipefail
# This script lists the 100 most recent S3 buckets populated from preview build jobs. It
# works by querying S3 for buckets with names matching our bucket naming prefix,
# then fetches the metadata files we generate with each build, outputting their results.
#
# For buckets built by `pull_request` and `push` jobs, the script will also tell you
# whether a given bucket can be safely deleted.
#
# Usage:
#
# # List all buckets
# ./scripts/ci/list-buckets.sh
#
# # List all buckets prefixed with "-pr-" (to filter pull_request builds)
# ./scripts/ci/list-buckets.sh pr
#
# # List all buckets prefixed with "-push-" (to filter push builds)
# ./scripts/ci/list-buckets.sh push
#
# # List only the buckets that can be safely deleted
# ./scripts/ci/list-buckets.sh [push | pr] --only-deletables
source ./scripts/ci/common.sh
bucket_prefix="$1"
buckets=$(get_recent_buckets $bucket_prefix)
buckets_as_array=($buckets)
bucket_count=${#buckets_as_array[@]}
only_deletables=false
# Only pr and push buckets can be flagged as deletable.
if [[ ( "$1" == "pr" || "$1" == "push" ) && "$2" == "--only-deletables" ]]; then
only_deletables=true
fi
# maybe_echo suppresses output to make lists more scriptable. There's probably a Bashier
# way to do this, but hey, it works.
maybe_echo() {
if [ $only_deletables == false ]; then
echo "$1"
fi
}
if [ "$bucket_count" == "0" ]; then
maybe_echo "No recent buckets matching the prefix $(origin_bucket_prefix)-${bucket_prefix} were found."
exit
fi
# Query for the bucket currently serving pulumi.com.
currently_deployed_bucket="$(curl -s https://www.pulumi.com/metadata.json | jq -r '.bucket' || echo '')"
maybe_echo "Found ${bucket_count} recent buckets matching the prefix $(origin_bucket_prefix)-${bucket_prefix}:"
# Variables used for determining whether a push-built bucket is safe to delete.
# The number of buckets beyond the currently deployed one that should be retained.
buckets_to_retain=10
# A counter for tracking how many builds behind the current website a given bucket is.
buckets_beyond_current=0
# A flag denoting whether the current website bucket exists in the current result set.
website_bucket_identified=false
# The array of deletable buckets, if any.
deletables=()
for bucket in $buckets; do
maybe_echo
maybe_echo "Fetching metadata for ${bucket}..."
metadata="$(aws s3 cp "s3://${bucket}/metadata.json" 2>/dev/null - || echo '')"
if [ ! -z "$metadata" ]; then
bucket_url="$(echo $metadata | jq -r '.url')"
bucket_name="$(echo $metadata | jq -r '.bucket')"
bucket_timestamp="$(echo $metadata | jq -r '.timestamp / 1000 | strftime("%Y-%m-%d %H:%M:%S UTC")')"
bucket_commit="$(echo $metadata | jq -r '.commit')"
maybe_echo "Bucket URL: ${bucket_url}"
maybe_echo "Bucket Name: ${bucket_name}"
maybe_echo "Synced At: ${bucket_timestamp}"
maybe_echo "Commit: https://github.com/pulumi/$(repo_name)/commit/${bucket_commit}"
# Call out whether this bucket is the one currently serving pulumi.com.
if [ "$bucket_name" == "$currently_deployed_bucket" ]; then
maybe_echo
maybe_echo "*"
maybe_echo "*"
maybe_echo "* ☝️ Head's up!"
maybe_echo "* This bucket (${bucket_name}) is currently serving pulumi.com."
maybe_echo "* https://www.pulumi.com/metadata.json"
maybe_echo "*"
maybe_echo "*"
website_bucket_identified=true
fi
# For push or pull_request buckets, indicate whether they can be safely deleted.
if [ "$1" == "push" ]; then
if [ "$buckets_beyond_current" -gt "$buckets_to_retain" ]; then
maybe_echo
maybe_echo "❌ This bucket is ${buckets_beyond_current} buckets behind the current website, so it can safely be deleted."
maybe_echo " aws s3 rb s3://${bucket_name} --force"
deletables+=($bucket_name)
fi
elif [ "$1" == "pr" ]; then
# Parse the bucket name for the PR number. A bit gross, but more reliable than
# asking GitHub for the PR associated with a commit, because commits are often
# removed when squashed or rebased.
pr_number="$(echo $bucket_name | sed "s/^$(origin_bucket_prefix)-pr-\([0-9]*\)-.*$/\1/")"
pr_metadata="$(curl \
-s \
-f \
-H "Authorization: token ${GITHUB_TOKEN}" \
"https://api.github.com/repos/pulumi/$(repo_name)/pulls/${pr_number}" || echo "{}")"
pr_state="$(echo $pr_metadata | jq -r '.state')"
if [ "$pr_state" == "closed" ]; then
maybe_echo
maybe_echo "❌ This bucket's PR state is ${pr_state} (https://github.com/pulumi/$(repo_name)/pull/${pr_number}), so it can safely be deleted."
maybe_echo " aws s3 rb s3://${bucket_name} --force"
deletables+=($bucket_name)
fi
fi
# If the current website bucket exists in this batch, note it, and increment the
# counter that'll determine whether an older bucket can be safely deleted.
if [ "$website_bucket_identified" == true ]; then
buckets_beyond_current=$((buckets_beyond_current+1))
fi
else
maybe_echo "Missing metadata file. This bucket may not have been built and tested successfully."
fi
done
maybe_echo
maybe_echo "---"
maybe_echo
maybe_echo "✅ To run browser tests on one of these buckets, run:"
maybe_echo " nvm use && make ensure && ./scripts/run-browser-tests.sh \"<bucket-url>\""
maybe_echo
maybe_echo "📌 To pin the website to one of these buckets, run:"
maybe_echo " pulumi -C infrastructure config set originBucketNameOverride \"<bucket-name>\""
maybe_echo " pulumi -C infrastructure up"
maybe_echo
maybe_echo "❌ To delete one of these buckets, run:"
maybe_echo " aws s3 rb \"s3://<bucket-name>\" --force"
maybe_echo
if [ ${#deletables} -gt 0 ]; then
maybe_echo "💥 To delete all buckets identified above as deletable, run:"
for deletable in ${deletables[@]}; do
if [ $only_deletables == true ]; then
echo "$deletable"
else
echo " aws s3 rb \"s3://${deletable}\" --force"
fi
done
maybe_echo
fi
+58
View File
@@ -0,0 +1,58 @@
#!/bin/bash
set -o errexit -o pipefail
# This script handles closed pull requests by finding all of their associated site-preview
# buckets and deleting them.
# See if we have the requisite credentials. If not, we might be in a fork, so exit.
if [ -z "${AWS_ACCESS_KEY_ID:-}" ] || [ -z "${AWS_SECRET_ACCESS_KEY:-}" ] || [ -z "${PULUMI_ACCESS_TOKEN:-}" ]; then
echo "Missing secret tokens. Exiting."
exit
fi
source ./scripts/ci/common.sh
if [[ "$GITHUB_EVENT_NAME" == "pull_request" && ! -z "$GITHUB_EVENT_PATH" ]]; then
event="$(cat "$GITHUB_EVENT_PATH")"
pr_number="$(echo $event | jq -r ".number")"
pr_action="$(echo $event | jq -r ".action")"
if [[ "$pr_action" == "closed" ]]; then
pr_comment_api_url="$(echo $event | jq -r ".pull_request._links.comments.href")"
# Find all commits associated with the PR.
pr_commits="$(curl \
-s \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/pulumi/$(repo_name)/pulls/${pr_number}/commits")"
# For each PR commit, if a bucket exists for it, delete it.
for commit in $(echo $pr_commits | jq -r ".[].sha"); do
pr_bucket_name="$(get_bucket_for_commit $commit)"
if [ ! -z "$pr_bucket_name" ]; then
echo "Found bucket ${pr_bucket_name} associated with commit ${commit}."
echo "Attempting to delete..."
# aws s3api head-bucket is a quick way to determine whether the bucket exists
# and we have access to it.
if aws s3api head-bucket --bucket "$pr_bucket_name" 2>/dev/null; then
aws s3 rb "s3://${pr_bucket_name}" --force
else
echo "Unable to delete ${pr_bucket_name}. Skipping."
fi
else
echo "No bucket found for commit ${commit}. Skipping."
fi
done
# Post a PR comment that any links to previously built previews will no longer work.
post_github_pr_comment \
"Site previews for this pull request have been removed. ✨" \
$pr_comment_api_url
else
echo "PR action was ${pr_action}. Skipping."
fi
fi
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
set -o errexit -o pipefail
# See if we have the requisite credentials. If not, we might be in a fork. In that case,
# run a PR build, but skip all the deployment stuff.
if [ -z "${AWS_ACCESS_KEY_ID:-}" ] || [ -z "${AWS_SECRET_ACCESS_KEY:-}" ] || [ -z "${PULUMI_ACCESS_TOKEN:-}" ]; then
echo "Missing secret tokens, possibly due to a forked PR."
echo "Running a build, but will skip the sync to S3 and Pulumi preview."
./scripts/ci/build.sh
exit
fi
aws sts get-caller-identity
./scripts/ci/build.sh
./scripts/ci/sync.sh
+31
View File
@@ -0,0 +1,31 @@
#!/bin/bash
set -o errexit -o pipefail
# This script uses the list-buckets script to find buckets that can be safely
# deleted, then deletes them. See that script for details, but in general, a bucket is
# deletable if and only if:
#
# * It's associated with a PR that's been closed.
echo "Finding deletable $1 buckets..."
buckets_to_remove="$(./scripts/ci/list-buckets.sh "$1" --only-deletables)"
if [ -z "$buckets_to_remove" ]; then
echo "None found."
exit
fi
echo
echo "Buckets to remove:"
echo "$buckets_to_remove"
echo
for bucket in $buckets_to_remove; do
echo "Removing ${bucket}..."
aws s3 rb "s3://${bucket}" --force
echo
done
echo "Done!"
+14
View File
@@ -0,0 +1,14 @@
#!/bin/bash
set -o errexit -o pipefail
# This script runs the bucket-removal script to clean up old buckets produced by PR and push jobs.
# See if we have the requisite credentials. If not, we might be in a fork, so exit.
if [ -z "${AWS_ACCESS_KEY_ID:-}" ] || [ -z "${AWS_SECRET_ACCESS_KEY:-}" ]; then
echo "Missing secret tokens, possibly due to a forked PR. Exiting."
exit
fi
./scripts/ci/remove-buckets.sh push
./scripts/ci/remove-buckets.sh pr
+93
View File
@@ -0,0 +1,93 @@
#!/bin/bash
set -o errexit -o pipefail
# This script takes the built Hugo site and:
# - creates a new S3 bucket named according to whether the action is a push or pull_request.
# - creates a list of all Hugo-generated client-side ("meta-refresh") redirects that
# - we'll use to produce proper 301s later.
# - pushes the content of the website into the new S3 bucket.
# - tests the built website, first for broken links, then with Cypress to ensure pages
# - render and behave properly.
# - emits a metadata file containing information about the commit and bucket, which
# - Pulumi will use to process its update.
# - writes a record to AWS Parameter Store relating the generated bucket to the commit
# - responsible for producing it.
# - Posts a PR comment back to GitHub, if applicable.
source ./scripts/ci/common.sh
# The docroot of the built website.
build_dir="public"
# The text file we'll write as an output result.
metadata_file="$(origin_bucket_metadata_filepath)"
# Verify we have at least 1000 index.html files in total across the site.
if [ ! "$(find $build_dir -type f | grep index.html | wc -l)" -ge 1000 ]; then
echo "Page-count check failed. Exiting."
exit 1
fi
# For previews, name the destination bucket with the PR number, to reduce the number of
# buckets we create and to facilitate shorter sync times.
destination_bucket="$(origin_bucket_prefix)-$(build_identifier)"
destination_bucket_uri="s3://${destination_bucket}"
# Make the bucket. If this fails, there are two explanations, given the way we're naming
# our buckets: either a previous run failed at some point after creating the bucket, in
# which case we should simply proceed (to repopulate it), or the bucket was somehow
# created in another account, in which case subsequent operations on the bucket will also
# fail, causing this script to exit nonzero. In either case, it's okay to continue.
aws s3 mb $destination_bucket_uri --region "$(aws_region)" || true
aws s3api put-bucket-tagging --bucket $destination_bucket --tagging "TagSet=[{$(aws_owner_tag)}]"
# Make the bucket an S3 website.
aws s3 website $destination_bucket_uri --index-document index.html --error-document 404.html
# Sync the local build directory to the bucket. Note that we do pass the --delete option
# here, since in most cases, we'll be continually updating a bucket associated with a PR;
# passing this option keeps the destination bucket clean.
echo "Synchronizing to $destination_bucket_uri..."
aws s3 sync "$build_dir" "$destination_bucket_uri" --acl public-read --delete --quiet
echo "Sync complete."
s3_website_url="http://${destination_bucket}.s3-website.$(aws_region).amazonaws.com"
echo "$s3_website_url"
# Set the content-type of latest-version explicitly. (Otherwise, it'll be set as binary/octet-stream.)
aws s3 cp "$build_dir/latest-version" "${destination_bucket_uri}/latest-version" \
--content-type "text/plain" --acl public-read --metadata-directive REPLACE
# At this point, we have a bucket that's suitable for deployment. As a result of this run,
# we leave a file in the project root indicating the name of the bucket that was generated
# and the associated commit SHA, and then we upload that file into the bucket as well, for
# reference. The Pulumi program will expect this file to exist, and will use the bucket
# name to set the CloudFront origin on the next Pulumi run.
#
# Why use a local file and not `pulumi config`, or some other persistence store? Because
# we need ensure that every CI job deploys only what it was responsible for building.
# Coupled with the locking we get from the Pulumi Service, using a local file is a safe
# way to ensure we're deploying what we just finished building and testing.
echo "Writing result metadata."
metadata='{
"timestamp": %s,
"commit": "%s",
"bucket": "%s",
"url": "%s"
}'
printf "$metadata" "$(current_time_in_ms)" "$(git_sha)" "$destination_bucket" "$s3_website_url" > "$metadata_file"
# Copy the file to the destination bucket, for future reference.
aws s3 cp "$metadata_file" "${destination_bucket_uri}/metadata.json" --region "$(aws_region)" --acl public-read
# Persist an association between the current commit and the bucket we just deployed to.
set_bucket_for_commit "$(git_sha)" "$destination_bucket" "$(aws_region)"
# Finally, post a comment to the PR that directs the user to the resulting bucket URL.
pr_comment_api_url="$(cat "$GITHUB_EVENT_PATH" | jq -r ".pull_request._links.comments.href")"
post_github_pr_comment \
"Your site preview for commit $(git_sha_short) is ready! :tada:\n\n${s3_website_url}." \
$pr_comment_api_url
echo "Done! The bucket website is now built and available at ${s3_website_url}."
+24
View File
@@ -0,0 +1,24 @@
#!/bin/bash
set -o errexit -o pipefail
yarn cache clean
hugo mod clean
rm -rf _vendor
rm -rf public
rm -rf node_modules
for dir in themes/* ; do
pushd $dir
hugo mod clean
rm -rf resources
rm -rf _vendor
rm -rf node_modules
rm -rf static/js
rm -rf static/css
rm -rf components/node_modules
rm -rf components/dist
rm -rf components/www
popd
done
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
BUILD_IDENTIFIER="$(git rev-parse HEAD)"
export REPO_THEME_PATH="themes/default/"
# Bundle filenames are exported for use with Hugo and theme scripts.
export CSS_BUNDLE="static/css/styles.${BUILD_IDENTIFIER}.css"
export JS_BUNDLE="static/js/bundle.min.${BUILD_IDENTIFIER}.js"
export REL_CSS_BUNDLE="/css/styles.${BUILD_IDENTIFIER}.css"
export REL_JS_BUNDLE="/js/bundle.min.${BUILD_IDENTIFIER}.js"
+42
View File
@@ -0,0 +1,42 @@
#!/bin/bash
set -o errexit -o pipefail
source ./scripts/common.sh
REQUIRED_GO="1.16"
REQUIRED_HUGO="0.81"
REQUIRED_NODE="$(cat .nvmrc)"
# Check for the required versions of Go, Hugo, Node, and Yarn.
if [[ -z "$(which go)" || -z "$(go version | grep ${REQUIRED_GO})" ]]; then
echo "This project uses Go version ${REQUIRED_GO}."
echo "See the README for the complete list of prerequisities and "
echo "https://golang.org/doc/install for help installing Go."
exit 1
fi
if [[ -z "$(which hugo)" || -z "$(hugo version | grep ${REQUIRED_HUGO})" ]]; then
echo "This project uses Hugo version ${REQUIRED_HUGO}."
echo "See the README for the complete list of prerequisities and "
echo "https://gohugo.io/getting-started/quick-start for help installing Hugo."
exit 1
fi
if [[ -z "$(which node)" || -z "$(node --version | grep ${REQUIRED_NODE})" ]]; then
echo "This project uses Node.js ${REQUIRED_NODE}."
echo "See the README for the complete list of prerequisities and "
echo "https://nodejs.org/en/download for help installing Node.js."
exit 1
fi
if [[ -z "$(which yarn)" ]]; then
echo "This project uses the Yarn package manager."
echo "See the README for the complete list of prerequisities and "
echo "https://yarnpkg.com/getting-started/install for help installing Yarn."
exit 1
fi
echo "Installing Node.js modules..."
yarn install
yarn --cwd themes/default run ensure
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash
node ./scripts/lint/lint-markdown.js
+313
View File
@@ -0,0 +1,313 @@
const fs = require("fs");
const yaml = require("js-yaml");
const markdownlint = require("markdownlint");
const path = require("path");
/**
* REGEX for grabbing the the front matter of a Hugo markdown file. Example:
*
* ---
* ...props
* ---
*/
const FRONT_MATTER_REGEX = /((^---\s*$[^]*?^---\s*$)|(^\+\+\+\s*$[^]*?^(\+\+\+|\.\.\.)\s*$))(\r\n|\r|\n|$)/m;
const AUTO_GENERATED_HEADING_REGEX = /###### Auto generated by ([a-z0-9]\w+)[/]([a-z0-9]\w+) on ([0-9]+)-([a-zA-z]\w+)-([0-9]\w+)/g;
/**
* Validates if a title exists, has length, and does not have a length over 60 characters.
* More info: https://moz.com/learn/seo/title-tag
*
* @param {string} title The title tag value for a given page.
*/
function checkPageTitle(title) {
if (!title) {
return "Missing page title";
} else if (typeof title === "string") {
const titleLength = title.trim().length;
if (titleLength === 0) {
return "Page title is empty";
} else if (titleLength > 60) {
return "Page title exceeds 60 characters";
}
} else {
return "Page title is not a valid string"
}
return null;
}
/**
* Validates that a meta description exists, has length, is not too short,
* and is not too long.
* More info: https://moz.com/learn/seo/meta-description
*
* @param {string} meta The meta description for a given page
*/
function checkPageMetaDescription(meta) {
if (!meta) {
return "Missing meta description";
} else if (typeof meta === "string") {
const metaLength = meta.trim().length;
if (metaLength === 0) {
return "Meta description is empty";
} else if (metaLength < 50) {
return "Meta description is too short. Must be at least 50 characters";
} else if (metaLength > 160) {
return "Meta descripiton is too long. Must be shorter than 160 characters";
}
} else {
return "Meta description is not a valid string";
}
return null;
}
/**
* Builds an array of markdown files to lint and checks each file's front matter
* for formatting errors.
*
* @param {string[]} paths An array of paths to search for markdown files.
* @param {Object} [result] The result object returned after finishing searching.
* @returns {Object} The markdown file paths to search and an error object for the files front matter.
*/
function searchForMarkdown(paths, result) {
// If the result arg does not exist we should create it.
if (!result) {
result = {
files: [],
frontMatter: {},
}
}
// Grab the first file in the list and generate
// its full path.
const file = paths[0];
const fullPath = path.resolve(__dirname, file);
// Check if the path is a directory
const isDirectory = fs.statSync(fullPath).isDirectory();
// Get the file suffix so we can grab the markdown files.
const fileParts = file.split(".");
const fileSuffix = fileParts[fileParts.length - 1];
// Ignore auto generated docs.
if (file.indexOf("/content/docs/reference/pkg") > -1) {
const remaining = paths.slice(1, paths.length);
return searchForMarkdown(remaining, result);
}
// If the path is a directory we want to add the contents of the directory
// to the list.
if (isDirectory) {
const contents = fs.readdirSync(fullPath).map(function (file) {
return fullPath + "/" + file;
});
paths[0] = contents;
// Flatten the array.
const newPaths = [].concat.apply([], paths);
return searchForMarkdown(newPaths, result);
// Else check if the file suffix is a markdown
// and add it the resulting file list.
}
if (fileSuffix === "md") {
try {
// Read the file contents so we can grab the file header.
const content = fs.readFileSync(fullPath, "utf8");
// Grab the file header.
const frontMatter = content.match(FRONT_MATTER_REGEX);
// Remove the dash blocks around the file header.
const fContent = frontMatter[0].split("---").join("");
// Read the yaml.
const obj = yaml.load(fContent);
// If the page is auto generated, a redirect, or not indexed do not parse the front matter.
const autoGenerated = obj.no_edit_this_page === true || content.match(AUTO_GENERATED_HEADING_REGEX);
const redirectPassthrough = typeof obj.redirect_to === "string";
const noIndex = obj.block_external_search_index === true;
const allowLongTitle = !!obj.allow_long_title;
const shouldCheckFrontMatter = !autoGenerated && !redirectPassthrough && !noIndex && !allowLongTitle;
if (shouldCheckFrontMatter) {
// Build the front matter error object and add the file path.
result.frontMatter[fullPath] = {
error: null,
title: checkPageTitle(obj.title),
metaDescription: checkPageMetaDescription(obj.meta_desc),
};
result.files.push(fullPath);
}
} catch (e) {
// Include the error message in the front matter error object
// so we can display it to the user.
result.frontMatter[fullPath] = {
error: e.message,
};
result.files.push(fullPath);
}
}
// If there are remaining paths in the list, keep going.
const remaining = paths.slice(1, paths.length);
if (remaining.length > 0) {
return searchForMarkdown(remaining, result);
}
return result;
}
/**
* Builds an array of markdown files to search through from a
* given path.
*
* @param {string} parentPath The path to search for markdown files
*/
function getMarkdownFiles(parentPath) {
const fullParentPath = path.resolve(__dirname, parentPath)
const dirs = fs.readdirSync(fullParentPath).map(function (dir) {
return path.join(parentPath, dir);
});
return searchForMarkdown(dirs);
}
/**
* Groups the result of linting a file for markdown errors.
*
* @param {Object} result Results of lint errors. See: https://github.com/DavidAnson/markdownlint#usage
* @return {Object} An object containing the file path and lint errors.
* @return {string} result.path The full path of the linted file.
* @return {Object[]} result.errors An array of error objects. Same as the result param.
*/
function groupLintErrorOutput(result) {
// Grab the keys of the result object.
const keys = Object.keys(result);
// Map over the key array so we can combine front matter errors
// with the markdown lint errors.
const combinedErrors = keys.map(function (key) {
// Get the lint and front matter errors.
const lintErrors = result[key];
const frontMatterErrors = filesToLint.frontMatter[key];
// If the front matter error check threw an error add it to the lint
// error array. Else add title and meta descriptoins if they exist.
if (frontMatterErrors.error) {
lintErrors.push({
lineNumber: "File Header",
ruleDescription: frontMatterErrors.error,
});
} else {
if (frontMatterErrors.title) {
lintErrors.push({
lineNumber: "File Header",
ruleDescription: frontMatterErrors.title,
});
}
if (frontMatterErrors.metaDescription) {
lintErrors.push({
lineNumber: "File Header",
ruleDescription: frontMatterErrors.metaDescription,
});
}
}
if (lintErrors.length > 0) {
return { path: key, errors: lintErrors };
}
return null;
});
// Filter out all null values from the combined result array.
const filteredErrors = combinedErrors.filter(function (err) {
return err !== null;
});
return filteredErrors;
}
// Build the lint object for the content directory.
const filesToLint = getMarkdownFiles(`../../themes/default/content`);
/**
* The config options for lint markdown files. All rules
* are enabled by default. The config object let us customize
* what rules we enfore and how we enforce them.
*
* See: https://github.com/DavidAnson/markdownlint
*/
const opts = {
// The array of markdown files to lint.
files: filesToLint.files,
config: {
// Allow inline HTML.
MD033: false,
// Do not enforce line length.
MD013: false,
// Don't force language specification on code blocks.
MD040: false,
// Allow hard tabs.
MD010: false,
// Allow puncuation in headers.
MD026: false,
// Allow dollars signs in code blocks without values
// immediately below the command.
MD014: false,
// Allow all code block styles in a file. Code block styles
// are created equal and we shall not discriminate.
MD046: false,
// Allow indents on unordered lists to be 4 spaces instead of 2.
MD007: { indent: 4 },
// Allow duplicate headings.
MD024: false,
// Allow headings to be indendented.
MD023: false,
// Allow blank lines in blockquotes.
MD028: false,
// Allow indentation in unordered lists.
MD007: false,
},
};
// Lint the markdown files.
const result = markdownlint.sync(opts);
// Group the lint errors by file.
const errors = groupLintErrorOutput(result);
// Get the total number of errors.
const errorsArray = errors.map(function (err) { return err.errors });
const errorsCount = [].concat.apply([], errorsArray).length;
// Create the error output string.
const errorOutput = errors.map(function (err) {
let msg = err.path + ":\n";
for (let i = 0; i < err.errors.length; i++) {
const error = err.errors[i];
msg += "Line " + error.lineNumber + ": " + error.ruleDescription;
msg += error.errorDetail ? " [" + error.errorDetail + "].\n" : ".\n";
}
return msg;
}).join("\n");
// If there are errors output the error string and exit
// the program with an error.
if (errors.length > 0) {
console.log(`
Markdown Lint Results:
- ${filesToLint.files.length} files parsed.
- ${errorsCount} errors found.
Errors:
${errorOutput}
`);
const noError = process.argv.indexOf("--no-error") > -1;
process.exit(noError ? 0 : 1);
}
console.log(`
Markdown Lint Results:
- ${filesToLint.files.length} files parsed.
- ${errorsCount} errors found.
`);
process.exit(0);
+26
View File
@@ -0,0 +1,26 @@
#!/bin/bash
set -o errexit -o pipefail
source ./scripts/common.sh
# Run an initial asset build if one hasn't been already.
pushd themes/default
if ! test -f "${CSS_BUNDLE}" || ! test -f "${JS_BUNDLE}"; then
echo "Running an initial build..."
yarn run ensure
yarn run build
fi
popd
if [ "$1" == "all" ]; then
# Run Hugo and the theme watchers concurrently.
yarn run concurrently --raw --kill-others \
"yarn --cwd themes/default watch" \
"hugo serve --buildDrafts --buildFuture | grep -v -e 'WARN .* REF_NOT_FOUND'"
exit
fi
# Just run Hugo.
hugo serve --buildDrafts --buildFuture | grep -v -e 'WARN .* REF_NOT_FOUND'
+1
View File
@@ -0,0 +1 @@
2.23.1
+3
View File
@@ -0,0 +1,3 @@
node_modules
static/js
static/css
+4 -4
View File
@@ -1,6 +1,6 @@
$fa-font-path: "/fonts/fontawesome";
@import "vendor/fontawesome/fontawesome.scss";
@import "vendor/fontawesome/fa-solid.scss";
@import "vendor/fontawesome/fa-regular.scss";
@import "vendor/fontawesome/fa-brands.scss";
@import "fontawesome/fontawesome.scss";
@import "fontawesome/fa-solid.scss";
@import "fontawesome/fa-regular.scss";
@import "fontawesome/fa-brands.scss";
+20
View File
@@ -0,0 +1,20 @@
// Animated Icons
// --------------------------
.#{$fa-css-prefix}-spin {
animation: fa-spin 2s infinite linear;
}
.#{$fa-css-prefix}-pulse {
animation: fa-spin 1s infinite steps(8);
}
@keyframes fa-spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@@ -0,0 +1,20 @@
// Bordered & Pulled
// -------------------------
.#{$fa-css-prefix}-border {
border: solid .08em $fa-border-color;
border-radius: .1em;
padding: .2em .25em .15em;
}
.#{$fa-css-prefix}-pull-left { float: left; }
.#{$fa-css-prefix}-pull-right { float: right; }
.#{$fa-css-prefix},
.fas,
.far,
.fal,
.fab {
&.#{$fa-css-prefix}-pull-left { margin-right: .3em; }
&.#{$fa-css-prefix}-pull-right { margin-left: .3em; }
}
+20
View File
@@ -0,0 +1,20 @@
// Base Class Definition
// -------------------------
.#{$fa-css-prefix},
.fas,
.far,
.fal,
.fab {
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
line-height: 1;
}
%fa-icon {
@include fa-icon;
}
@@ -0,0 +1,6 @@
// Fixed Width Icons
// -------------------------
.#{$fa-css-prefix}-fw {
text-align: center;
width: $fa-fw-width;
}
File diff suppressed because it is too large Load Diff
+23
View File
@@ -0,0 +1,23 @@
// Icon Sizes
// -------------------------
// makes the font 33% larger relative to the icon container
.#{$fa-css-prefix}-lg {
font-size: (4em / 3);
line-height: (3em / 4);
vertical-align: -.0667em;
}
.#{$fa-css-prefix}-xs {
font-size: .75em;
}
.#{$fa-css-prefix}-sm {
font-size: .875em;
}
@for $i from 1 through 10 {
.#{$fa-css-prefix}-#{$i}x {
font-size: $i * 1em;
}
}
+18
View File
@@ -0,0 +1,18 @@
// List Icons
// -------------------------
.#{$fa-css-prefix}-ul {
list-style-type: none;
margin-left: $fa-li-width * 5/4;
padding-left: 0;
> li { position: relative; }
}
.#{$fa-css-prefix}-li {
left: -$fa-li-width;
position: absolute;
text-align: center;
width: $fa-li-width;
line-height: inherit;
}
+56
View File
@@ -0,0 +1,56 @@
// Mixins
// --------------------------
@mixin fa-icon {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
display: inline-block;
font-style: normal;
font-variant: normal;
font-weight: normal;
line-height: 1;
}
@mixin fa-icon-rotate($degrees, $rotation) {
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})";
transform: rotate($degrees);
}
@mixin fa-icon-flip($horiz, $vert, $rotation) {
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)";
transform: scale($horiz, $vert);
}
// Only display content to screen readers. A la Bootstrap 4.
//
// See: http://a11yproject.com/posts/how-to-hide-content/
@mixin sr-only {
border: 0;
clip: rect(0, 0, 0, 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
// Use in conjunction with .sr-only to only display content when it's focused.
//
// Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
//
// Credit: HTML5 Boilerplate
@mixin sr-only-focusable {
&:active,
&:focus {
clip: auto;
height: auto;
margin: 0;
overflow: visible;
position: static;
width: auto;
}
}
@@ -0,0 +1,24 @@
// Rotated & Flipped Icons
// -------------------------
.#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); }
.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
.#{$fa-css-prefix}-flip-both, .#{$fa-css-prefix}-flip-horizontal.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(-1, -1, 2); }
// Hook for IE8-9
// -------------------------
:root {
.#{$fa-css-prefix}-rotate-90,
.#{$fa-css-prefix}-rotate-180,
.#{$fa-css-prefix}-rotate-270,
.#{$fa-css-prefix}-flip-horizontal,
.#{$fa-css-prefix}-flip-vertical,
.#{$fa-css-prefix}-flip-both {
filter: none;
}
}
@@ -0,0 +1,5 @@
// Screen Readers
// -------------------------
.sr-only { @include sr-only; }
.sr-only-focusable { @include sr-only-focusable; }
File diff suppressed because it is too large Load Diff
+31
View File
@@ -0,0 +1,31 @@
// Stacked Icons
// -------------------------
.#{$fa-css-prefix}-stack {
display: inline-block;
height: 2em;
line-height: 2em;
position: relative;
vertical-align: middle;
width: ($fa-fw-width*2);
}
.#{$fa-css-prefix}-stack-1x,
.#{$fa-css-prefix}-stack-2x {
left: 0;
position: absolute;
text-align: center;
width: 100%;
}
.#{$fa-css-prefix}-stack-1x {
line-height: inherit;
}
.#{$fa-css-prefix}-stack-2x {
font-size: 2em;
}
.#{$fa-css-prefix}-inverse {
color: $fa-inverse;
}
File diff suppressed because it is too large Load Diff
+22
View File
@@ -0,0 +1,22 @@
/*!
* Font Awesome Free 5.8.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
@import 'variables';
@font-face {
font-family: 'Font Awesome 5 Brands';
font-style: normal;
font-weight: normal;
font-display: $fa-font-display;
src: url('#{$fa-font-path}/fa-brands-400.eot');
src: url('#{$fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'),
url('#{$fa-font-path}/fa-brands-400.woff2') format('woff2'),
url('#{$fa-font-path}/fa-brands-400.woff') format('woff'),
url('#{$fa-font-path}/fa-brands-400.ttf') format('truetype'),
url('#{$fa-font-path}/fa-brands-400.svg#fontawesome') format('svg');
}
.fab {
font-family: 'Font Awesome 5 Brands';
}
+23
View File
@@ -0,0 +1,23 @@
/*!
* Font Awesome Free 5.8.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
@import 'variables';
@font-face {
font-family: 'Font Awesome 5 Free';
font-style: normal;
font-weight: 400;
font-display: $fa-font-display;
src: url('#{$fa-font-path}/fa-regular-400.eot');
src: url('#{$fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'),
url('#{$fa-font-path}/fa-regular-400.woff2') format('woff2'),
url('#{$fa-font-path}/fa-regular-400.woff') format('woff'),
url('#{$fa-font-path}/fa-regular-400.ttf') format('truetype'),
url('#{$fa-font-path}/fa-regular-400.svg#fontawesome') format('svg');
}
.far {
font-family: 'Font Awesome 5 Free';
font-weight: 400;
}
+24
View File
@@ -0,0 +1,24 @@
/*!
* Font Awesome Free 5.8.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
@import 'variables';
@font-face {
font-family: 'Font Awesome 5 Free';
font-style: normal;
font-weight: 900;
font-display: $fa-font-display;
src: url('#{$fa-font-path}/fa-solid-900.eot');
src: url('#{$fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'),
url('#{$fa-font-path}/fa-solid-900.woff2') format('woff2'),
url('#{$fa-font-path}/fa-solid-900.woff') format('woff'),
url('#{$fa-font-path}/fa-solid-900.ttf') format('truetype'),
url('#{$fa-font-path}/fa-solid-900.svg#fontawesome') format('svg');
}
.fa,
.fas {
font-family: 'Font Awesome 5 Free';
font-weight: 900;
}
+16
View File
@@ -0,0 +1,16 @@
/*!
* Font Awesome Free 5.8.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
@import 'variables';
@import 'mixins';
@import 'core';
@import 'larger';
@import 'fixed-width';
@import 'list';
@import 'bordered-pulled';
@import 'animated';
@import 'rotated-flipped';
@import 'stacked';
@import 'icons';
@import 'screen-reader';
+6
View File
@@ -0,0 +1,6 @@
/*!
* Font Awesome Free 5.8.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
@import 'variables';
@import 'shims';
+1 -1
View File
@@ -148,7 +148,7 @@ main {
}
.tag {
@apply text-sm lowercase border border-gray-200 rounded py-1 px-2 mr-1 transition-all;
@apply text-sm lowercase border border-gray-200 rounded py-1 px-2 mr-1;
&.tag-blog {
@apply bg-white text-blue-600;
+4
View File
@@ -0,0 +1,4 @@
.stencil/
package-lock.json
dist/
www/
+3
View File
@@ -0,0 +1,3 @@
module:
hugoVersion:
min: 0.81.0
+3
View File
@@ -0,0 +1,3 @@
module github.com/pulumi/pulumi-hugo/themes/default
go 1.16
@@ -15,13 +15,13 @@
{{ $isAPIDoc := and (hasPrefix .Path "docs/reference/pkg/") (ne .Path "docs/reference/pkg/_index.md") }}
{{ if not (or $isCLICommand $isAPIDoc $.Page.Params.no_edit_this_page) }}
<li>
<a data-track="edit-page" class="text-gray-600 hover:text-blue-700 text-xs" href="{{ $.Site.Params.repositoryURL }}/edit/{{ $.Site.Params.repositoryBranch }}/content/{{ .Path }}" target="_blank">
<a data-track="edit-page" class="text-gray-600 hover:text-blue-700 text-xs" href="{{ $.Site.Params.repositoryURL }}/edit/{{ $.Site.Params.repositoryBranch }}/{{ getenv "REPO_THEME_PATH" }}content/{{ .Path }}" target="_blank">
<i class="fas fa-edit mr-2" style="width: 14px"></i>Edit this Page
</a>
</li>
{{ end }}
<li>
<a data-track="request-change" class="text-gray-600 hover:text-blue-700 text-xs" href="{{ $.Site.Params.repositoryURL }}/issues/new?body=File: [{{ .Path }}]({{ $.Page.Permalink }})" target="_blank">
<a data-track="request-change" class="text-gray-600 hover:text-blue-700 text-xs" href="{{ $.Site.Params.repositoryURL }}/issues/new?body=File: [{{ getenv "REPO_THEME_PATH" }}content/{{ .Path }}]({{ $.Page.Permalink }})" target="_blank">
<i class="far fa-check-square mr-2" style="width: 14px"></i>Request a Change
</a>
</li>
@@ -7,10 +7,12 @@
{{/* Get the pages in the current directory. */}}
{{ $unsortedPages := slice $currentPage }}
{{ range $index, $element := readDir (printf "content/%s" $currentPage.File.Dir) }}
{{ $page := $currentPage.GetPage $element.Name }}
{{ if eq $currentPage.Dir $currentPage.Parent.Dir }}
{{ $unsortedPages = $unsortedPages | append $currentPage.Parent }}
{{ end }}
{{ range $index, $page := .Page.CurrentSection.Pages }}
{{ if and (gt $page.Weight 0) (ne $page.RelPermalink $currentPage.RelPermalink) }}
{{ $unsortedPages = $unsortedPages | append $page -}}
{{ $unsortedPages = $unsortedPages | append $page }}
{{ end }}
{{ end }}
@@ -1,5 +1,9 @@
{{- $file := readFile "/docs/reference/cli/pulumi.md" -}}
{{/* Remove front matter and "Auto generated by..." suffix. */}}
{{- $file = replaceRE "(?s)---.*---" "" $file -}}
{{- $file = replaceRE "(?m)^###### Auto generated by .*$" "" $file -}}
{{- markdownify $file -}}
{{/* Fetch the current version of the Pulumi CLI doc." suffix. */}}
{{- $json := getJSON "https://api.github.com/repos/pulumi/docs/contents/content/docs/reference/cli/pulumi.md" }}
{{ with $json }}
{{ $content := base64Decode .content }}
{{/* Remove front matter and "Auto generated by..." suffix. */}}
{{- $content = replaceRE "(?s)---.*---" "" $content -}}
{{- $content = replaceRE "(?m)^###### Auto generated by .*$" "" $content -}}
{{- markdownify $content -}}
{{ end }}
+33
View File
@@ -0,0 +1,33 @@
{
"name": "pulumi-hugo-current",
"version": "0.0.1",
"private": true,
"scripts": {
"ensure": "yarn install && yarn --cwd components install",
"test": "yarn run test-components",
"watch": "yarn run concurrently 'yarn run watch-css' 'yarn run watch-js' 'yarn run watch-components'",
"build": "yarn run build-css && yarn run build-js && yarn run build-components",
"test-components": "yarn --cwd components run test",
"watch-css": "yarn run chokidar 'assets/sass/**/*.scss' -c \"yarn run --silent node-sass assets/sass/styles.scss | yarn run postcss --config assets/config --output ${CSS_BUNDLE}\"",
"watch-js": "yarn run tsc --watch --preserveWatchOutput --outFile ${JS_BUNDLE}",
"watch-components": "yarn --cwd components run start",
"build-css": "yarn run --silent node-sass assets/sass/styles.scss | yarn run postcss --output ${CSS_BUNDLE}",
"build-js": "yarn run tsc --outFile ${JS_BUNDLE}",
"build-components": "yarn --cwd components run build"
},
"dependencies": {
"@fullhuman/postcss-purgecss": "^2.0.6",
"autoprefixer": "^9.6.0",
"chokidar-cli": "^2.1.0",
"clipboard-polyfill": "^2.8.1",
"concurrently": "^5.2.0",
"cssnano": "^4.1.10",
"node-sass": "^4.14.1",
"postcss-cli": "^6.1.3",
"tailwindcss": "^1.0.4",
"typescript": "^3.9.6"
}
}
+96
View File
@@ -0,0 +1,96 @@
/**
* Configuration file for PostCSS. This is only used as part of the Hugo pipeline
* build process for our Sass files, since we run the resulting CSS through PostCSS
* at the end to do more transformations.
*/
// Note whether we're in "production" mode, so we can avoid doing post-processing and
// optimization during development.
const isProduction = process.env.NODE_ENV === "production";
module.exports = {
plugins: [
// TailwindCSS
require("tailwindcss")("./tailwind.config.js"),
// Apply vendor prefixes for CSS features that aren't
// fully supported yet.
isProduction ? require("autoprefixer")({
overrideBrowserslist: [
"last 2 versions"
]
}) : null,
// Remove whitespace, comments and other safe things.
// https://cssnano.co/guides/getting-started/
isProduction ? require("cssnano")({
preset: [
"default",
{
discardComments: {
removeAll: true,
},
},
],
}) : null,
// Use PurgeCSS to remove unused classes for better page speed.
// Docs: https://purgecss.com/plugins/postcss.html
isProduction ? require("@fullhuman/postcss-purgecss")({
// Specify the paths to all of the template files in your project
content: [
// All layout files.
"./layouts/**/*.html",
// Some of our scripts reference CSS classes.
"./assets/js/**/*.js",
// Look for CSS classes in our Markdown content. We use `glob` explicitly here so we can ignore the
// files for the API docs in ./content/docs/reference/pkg/**/* because it includes a large number of
// files that significantly impacts build time (~25 seconds vs. many minutes). Instead, we'll only look
// for CSS classes in a subset of packages for NodeJS and Python, which should be representative of all
// the other packages.
...require("glob").sync("./content/**/*.md", {
ignore: "./content/docs/reference/pkg/**/*"
}),
"./content/docs/reference/pkg/nodejs/pulumi/aws/**/*.md",
"./content/docs/reference/pkg/python/pulumi/**/*.md",
"./content/docs/reference/pkg/aws/s3/bucket.md",
"./content/docs/reference/pkg/aws/cognito/userpool.md",
"./content/docs/reference/pkg/_index.md",
],
// Whitelist specific classes that were being removed.
whitelist: [
"supported-cicd-platforms", ":not", ":target", "md:max-w-lg", "blink", "typing",
"char", "resource-deprecated", "btn-scroll-top", "lg:btn-purple-transparent", "section-docs",
"supporting-types"
],
// Whitelist custom parent selectors and their children.
whitelistPatterns: [/^fa-/, /^hs-/, /^highlight$/, /^pagination$/, /^code-/, /^copy-/, /^carousel/, /^bg-/, /^st-/],
whitelistPatternsChildren: [
/^hs-/,
/^highlight$/,
/^pagination$/,
/^code-/,
/^copy-/,
/^carousel/,
/^st-/,
// Whitelist our web components along with any of their descendent selectors.
/^pulumi-chooser/,
/^pulumi-tooltip/,
/^pulumi-banner/,
/^pulumi-convert/,
/^pulumi-greenhouse-jobs-list/,
],
// We need to extract the Tailwind screen size selectors (e.g. sm, md, lg)
// so that we do not strip them out. As long as a class name appears in the HTML
// in its entirety, PurgeCSS will not remove it.
// Ex. https://tailwindcss.com/docs/controlling-file-size/#writing-purgeable-html
defaultExtractor: content => content.match(/[\w-/:]*[\w-/:]/g) || [],
}) : null,
],
};
+136
View File
@@ -0,0 +1,136 @@
// Tailwind configuration. Changes to this file require a dev-server restart.
//
// Configuration docs:
// https://tailwindcss.com/docs/configuration
//
// Default configuration:
// https://github.com/tailwindcss/tailwindcss/blob/master/stubs/defaultConfig.stub.js
const defaultTheme = require('tailwindcss/defaultTheme');
const brand = {
purple: "#512668",
orange: "#ee975c",
green: "#2fc89f",
blue: "#52a6da",
}
const white = defaultTheme.colors.white;
const black = defaultTheme.colors.black;
const gray = defaultTheme.colors.gray;
const red = defaultTheme.colors.red;
const yellow = defaultTheme.colors.yellow;
const transparent = defaultTheme.colors.transparent;
const purple = {
100: "#d7cddc",
200: "#a48bb3",
300: "#745687",
400: "#654276",
500: brand.purple,
600: "#421d57",
700: "#371a47",
800: "#2a1337",
900: "#180b1f",
}
const blue = {
100: "#f5fbff",
200: "#cae6f7",
300: "#9dd1f0",
400: "#73b7e7",
500: brand.blue,
600: "#4387c7",
700: "#3671b0",
800: "#365881",
900: "#334866",
}
const orange = {
100: "#fff7eb",
200: "#fde6c4",
300: "#fad49e",
400: "#f6ba7e",
500: brand.orange,
600: "#e17d47",
700: "#d86131",
800: "#ba4a2c",
900: "#993d29",
}
const green = {
100: "#e0fff2",
200: "#b2fbe0",
300: "#81eeca",
400: "#4ce1b4",
500: brand.green,
600: "#25a78b",
700: "#1d8673",
800: "#19675b",
900: "#155148",
}
const fuschia= {
100: "#fcdbff",
200: "#f5b9fd",
300: "#eb9efa",
400: "#d975f5",
500: "#c75ceb",
600: "#ab3ad4",
700: "#9135b6",
800: "#6c2f89",
900: brand.purple,
};
module.exports = {
theme: {
extend: {
fontFamily: {
display: [
"Ubuntu",
...defaultTheme.fontFamily.sans,
],
body: [
"Open Sans",
...defaultTheme.fontFamily.sans,
],
mono: [
"Source Code Pro",
...defaultTheme.fontFamily.mono,
]
},
},
colors: {
white,
black,
gray,
red,
yellow,
purple,
blue,
orange,
green,
fuschia,
transparent,
},
maxHeight: {
'25': '25vh',
'50': '50vh',
'75': '75vh',
'100': '100vh',
}
},
variants: {
margin: [
"responsive",
"hover",
],
padding: [
"responsive",
"group-hover",
"hover",
],
}
}
+27
View File
@@ -0,0 +1,27 @@
{
"compilerOptions": {
"allowJs": true,
"removeComments": true,
"sourceMap": true,
"sourceRoot": "/"
},
"files": [
"assets/js/main.js",
"assets/js/nav.js",
"assets/js/carousel.js",
"assets/js/chooser.js",
"assets/js/price-toggle.js",
"assets/js/noselect.js",
"assets/js/tracking.js",
"assets/js/docs-feedback.js",
"assets/js/event-filtering.js",
"assets/js/copybutton.js",
"assets/js/code-tabbed.js",
"assets/js/resources.js",
"node_modules/clipboard-polyfill/dist/clipboard-polyfill.js",
"assets/js/search.js",
],
"exclude": [
"node_modules"
]
}
File diff suppressed because it is too large Load Diff
+457
View File
@@ -0,0 +1,457 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@babel/code-frame@^7.0.0":
version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658"
integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==
dependencies:
"@babel/highlight" "^7.12.13"
"@babel/helper-validator-identifier@^7.12.11":
version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed"
integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==
"@babel/highlight@^7.12.13":
version "7.13.10"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1"
integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==
dependencies:
"@babel/helper-validator-identifier" "^7.12.11"
chalk "^2.0.0"
js-tokens "^4.0.0"
"@types/normalize-package-data@^2.4.0":
version "2.4.0"
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==
ansi-regex@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
dependencies:
color-convert "^1.9.0"
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
dependencies:
color-convert "^2.0.1"
argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
dependencies:
sprintf-js "~1.0.2"
chalk@^2.0.0:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chalk@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a"
integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
cliui@^7.0.2:
version "7.0.4"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
dependencies:
string-width "^4.2.0"
strip-ansi "^6.0.0"
wrap-ansi "^7.0.0"
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
dependencies:
color-name "1.1.3"
color-convert@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
dependencies:
color-name "~1.1.4"
color-name@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
concurrently@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-6.0.0.tgz#c1a876dd99390979c71f8c6fe6796882f3a13199"
integrity sha512-Ik9Igqnef2ONLjN2o/OVx1Ow5tymVvvEwQeYCQdD/oV+CN9oWhxLk7ibcBdOtv0UzBqHCEKRwbKceYoTK8t3fQ==
dependencies:
chalk "^4.1.0"
date-fns "^2.16.1"
lodash "^4.17.20"
read-pkg "^5.2.0"
rxjs "^6.6.3"
spawn-command "^0.0.2-1"
supports-color "^8.1.0"
tree-kill "^1.2.2"
yargs "^16.2.0"
date-fns@^2.16.1:
version "2.19.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.19.0.tgz#65193348635a28d5d916c43ec7ce6fbd145059e1"
integrity sha512-X3bf2iTPgCAQp9wvjOQytnf5vO5rESYRXlPIVcgSbtT5OTScPcsf9eZU+B/YIkKAtYr5WeCii58BgATrNitlWg==
emoji-regex@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
entities@~2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f"
integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==
error-ex@^1.3.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
dependencies:
is-arrayish "^0.2.1"
escalade@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
has-flag@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
has@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
dependencies:
function-bind "^1.1.1"
hosted-git-info@^2.1.4:
version "2.8.8"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
is-core-module@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a"
integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==
dependencies:
has "^1.0.3"
is-fullwidth-code-point@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
js-yaml@^3.13.1:
version "3.14.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
json-parse-even-better-errors@^2.3.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
lines-and-columns@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
linkify-it@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf"
integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==
dependencies:
uc.micro "^1.0.1"
lodash@^4.17.20:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
markdown-it@10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-10.0.0.tgz#abfc64f141b1722d663402044e43927f1f50a8dc"
integrity sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==
dependencies:
argparse "^1.0.7"
entities "~2.0.0"
linkify-it "^2.0.0"
mdurl "^1.0.1"
uc.micro "^1.0.5"
markdownlint@^0.17.2:
version "0.17.2"
resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.17.2.tgz#de0ab144fbf314fedadcb8a4ce0db9ea819f91a5"
integrity sha512-vsxopn0qEdm0P2XI3S9sVA+jvjKjR8lHZ+0FKlusth+1UK9tI29mRFkKeZPERmbWsMehJcogfMieBUkMgNEFkQ==
dependencies:
markdown-it "10.0.0"
mdurl@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=
normalize-package-data@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==
dependencies:
hosted-git-info "^2.1.4"
resolve "^1.10.0"
semver "2 || 3 || 4 || 5"
validate-npm-package-license "^3.0.1"
parse-json@^5.0.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
dependencies:
"@babel/code-frame" "^7.0.0"
error-ex "^1.3.1"
json-parse-even-better-errors "^2.3.0"
lines-and-columns "^1.1.6"
path-parse@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
read-pkg@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc"
integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==
dependencies:
"@types/normalize-package-data" "^2.4.0"
normalize-package-data "^2.5.0"
parse-json "^5.0.0"
type-fest "^0.6.0"
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
resolve@^1.10.0:
version "1.20.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
dependencies:
is-core-module "^2.2.0"
path-parse "^1.0.6"
rxjs@^6.6.3:
version "6.6.6"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.6.tgz#14d8417aa5a07c5e633995b525e1e3c0dec03b70"
integrity sha512-/oTwee4N4iWzAMAL9xdGKjkEHmIwupR3oXbQjCKywF1BeFohswF3vZdogbmEF6pZkOsXTzWkrZszrWpQTByYVg==
dependencies:
tslib "^1.9.0"
"semver@2 || 3 || 4 || 5":
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
spawn-command@^0.0.2-1:
version "0.0.2-1"
resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0"
integrity sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=
spdx-correct@^3.0.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==
dependencies:
spdx-expression-parse "^3.0.0"
spdx-license-ids "^3.0.0"
spdx-exceptions@^2.1.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d"
integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==
spdx-expression-parse@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679"
integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==
dependencies:
spdx-exceptions "^2.1.0"
spdx-license-ids "^3.0.0"
spdx-license-ids@^3.0.0:
version "3.0.7"
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65"
integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
string-width@^4.1.0, string-width@^4.2.0:
version "4.2.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5"
integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.0"
strip-ansi@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
dependencies:
ansi-regex "^5.0.0"
supports-color@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
dependencies:
has-flag "^3.0.0"
supports-color@^7.1.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
dependencies:
has-flag "^4.0.0"
supports-color@^8.1.0:
version "8.1.1"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
dependencies:
has-flag "^4.0.0"
tree-kill@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
tslib@^1.9.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
type-fest@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b"
integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==
uc.micro@^1.0.1, uc.micro@^1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
validate-npm-package-license@^3.0.1:
version "3.0.4"
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==
dependencies:
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
y18n@^5.0.5:
version "5.0.5"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18"
integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==
yargs-parser@^20.2.2:
version "20.2.7"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a"
integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==
yargs@^16.2.0:
version "16.2.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
dependencies:
cliui "^7.0.2"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
string-width "^4.2.0"
y18n "^5.0.5"
yargs-parser "^20.2.2"