Initial commit
This commit is contained in:
@@ -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 }}
|
||||
@@ -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 }}
|
||||
@@ -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 }}
|
||||
@@ -0,0 +1,5 @@
|
||||
_vendor
|
||||
node_modules
|
||||
resources
|
||||
themes/*/resources
|
||||
public
|
||||
+193
@@ -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 — 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:
|
||||
|
||||
```
|
||||

|
||||
```
|
||||
|
||||
#### 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 — provided its `date` has passed and its `draft` status is no longer `true` — 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).
|
||||
@@ -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
|
||||
@@ -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** > **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).
|
||||
@@ -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')"
|
||||
@@ -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 — 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).
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
Executable
+9
@@ -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'
|
||||
Executable
+29
@@ -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"
|
||||
Executable
+156
@@ -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
|
||||
}
|
||||
Executable
+169
@@ -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
|
||||
Executable
+58
@@ -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
|
||||
Executable
+17
@@ -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
|
||||
Executable
+31
@@ -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!"
|
||||
Executable
+14
@@ -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
|
||||
Executable
+93
@@ -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}."
|
||||
Executable
+24
@@ -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
|
||||
Executable
+10
@@ -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"
|
||||
Executable
+42
@@ -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
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
node ./scripts/lint/lint-markdown.js
|
||||
@@ -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);
|
||||
Executable
+26
@@ -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'
|
||||
@@ -0,0 +1 @@
|
||||
2.23.1
|
||||
@@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
static/js
|
||||
static/css
|
||||
@@ -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";
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
+1366
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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; }
|
||||
+2062
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
+1381
File diff suppressed because it is too large
Load Diff
@@ -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';
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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';
|
||||
@@ -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';
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
.stencil/
|
||||
package-lock.json
|
||||
dist/
|
||||
www/
|
||||
@@ -0,0 +1,3 @@
|
||||
module:
|
||||
hugoVersion:
|
||||
min: 0.81.0
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
],
|
||||
};
|
||||
@@ -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",
|
||||
],
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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"
|
||||
Reference in New Issue
Block a user