Rename env-sample-sync -> ess

This commit is contained in:
Adriano Caloiaro 2023-09-26 08:03:12 -06:00
parent 716cf43c7c
commit 50cff7efb2
No known key found for this signature in database
GPG key ID: 920633857147D83D
3 changed files with 305 additions and 87 deletions

View file

@ -25,7 +25,7 @@ These are the projects I like to work on, in no particular order. I prefer to op
</tr>
<tr>
<td><a href="#env-sample-sync-httpsgithubcomacaloiaroenv-sample-sync">env-sample-sync</a></td>
<td><a href="#ess-httpsgithubcomacaloiaroess">ess (env sample sync)</a></td>
<td>Automatically keep .env files in sync with env.sample</td>
</tr>
@ -88,13 +88,13 @@ nq.Enqueue(ctx, &jobs.Job{
Neat.
## env-sample-sync (https://github.com/acaloiaro/env-sample-sync)
## ess (https://github.com/acaloiaro/ess)
Automatically keep `.env` files in sync with `env.sample`.
env-sample-sync - automatically keep `.env` files in sync with `env.sample`.
Your `.env` is always in `.gitignore`, right...right?! So how do you document what goes in it? Easy, add a file named `env.sample` to your project and check it in to git.
The problem is that `env.sample` rarely gets updated when new environment variables are added to applications. `env-sample-sync` is the solution to that problem.
The problem is that `env.sample` rarely gets updated when new environment variables are added to applications. `ess` is the solution to that problem.
Users can document `.env` with comments and extensive details about how env var values should be structured, or where one can get/generate values for them.
@ -107,7 +107,7 @@ APPLICATION_SECRET=supersekrit
FOO="My super secret value for foo"
```
**`env-sample-sync` converts the above `.env` example to:**
**`ess` converts the above `.env` example to:**
```

View file

@ -5,9 +5,9 @@ title: Document your secrets, please
alias: /posts/2023-07-20-secrets-should-be-documented
---
## TL;DR [env-sample-sync](https://github.com/acaloiaro/env-sample-sync/) automates syncing `.env` with `env.sample`
## TL;DR [ess](https://github.com/acaloiaro/ess/) automates syncing `.env` with `env.sample`
It's [available here on Github](https://github.com/acaloiaro/env-sample-sync/).
It's [available here on Github](https://github.com/acaloiaro/ess/).
## The problem
@ -71,7 +71,7 @@ Regardless of where they come from, `.env` files are where the documentation hap
Env sample files are where our secret and configuration documentation lives in revision control. They should be _generated_ and checked into revision control in an automated manner every time `.env` changes. `env.sample` files are for humans, not machines, and they should look something like this:
{{< image src="/img/document-your-secrets.png" alt="env.sample generated with env-sample-sync" position="center" style="border-radius: 12px; height: 500px;" >}}
{{< image src="/img/document-your-secrets.png" alt="env.sample generated with ess" position="center" style="border-radius: 12px; height: 500px;" >}}
> Aside: This is not the **best** sample file example, as it was written by me, to me. If it was written for others, I would document how/where to generate each secret.
Sample files are especially useful when no out-of-band credentials can be shared with developers. Through `.env` file comments, sample files are able to document not only where to retrieve secret values, but _which_ configurations and secrets are required by projects, along with sensible defaults and example values.
@ -88,13 +88,13 @@ MY_NEW_FEATURE=disabled
**When no out-of-band credential sharing is possible `env.sample` should be copied to `.env` when starting development on new projects**
### `env-sample-sync` utility
### `ss` utility
I created [env-sample-sync](https://github.com/acaloiaro/env-sample-sync/) to solve this problem. While I think it works great, I encourage you and your team to automate `env.sample` generation in whatever way you see fit. I use `env-sample-sync` on every one of my projects today.
I created [ess](https://github.com/acaloiaro/ess/) to solve this problem. While I think it works great, I encourage you and your team to automate `env.sample` generation in whatever way you see fit. I use `ess` on every one of my projects today.
`env-sample-sync` can be run manually or as a pre-commit hook, ensuring that any time `.env` changes, the change is documented in the form of an updated sample.
`ess` can be run manually or as a pre-commit hook, ensuring that any time `.env` changes, the change is documented in the form of an updated sample.
Using it with projects is as simple as running `env-sample-sync install` in any git repository, activating the pre-commit hook.
Using it with projects is as simple as running `ess install` in any git repository, activating the pre-commit hook.
It also supports custom example values, e.g.
@ -104,7 +104,7 @@ Given the following `.env`
FOO=My secret foo
{{< /code >}}
Run with `env-sample-sync install --example=FOO="Fetch your own foo values from https://example.com/foogen"`
Run with `ess install --example=FOO="Fetch your own foo values from https://example.com/foogen"`
Results in the following `env.sample` upon next commit:

View file

@ -7,37 +7,76 @@ body {
font-size: 20px;
color: #404040;
position: relative;
background-color: {{ site.page-col }};
{% if site.page-img %}
background-color: {
{
site.page-col
}
}
;
{
% if site.page-img %
}
background-image: url({{ site.page-img }});
background-attachment: fixed;
{% endif %}
{
% endif %
}
}
p {
line-height: 1.4;
margin: 30px 0;
}
li {
line-height: 1.2;
}
h1,h2,h3,h4,h5,h6 {
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-weight: 800;
}
a {
color: {{ site.link-col }};
color: {
{
site.link-col
}
}
;
}
a:hover,
a:focus {
color: {{ site.hover-col }};
color: {
{
site.hover-col
}
}
;
}
blockquote {
color: #808080;
font-style: italic;
}
blockquote p:first-child {
margin-top: 0;
}
hr.small {
max-width: 100px;
margin: 15px auto;
@ -49,6 +88,7 @@ hr.small {
.main-content {
padding-top: 80px;
}
@media only screen and (min-width: 768px) {
.main-content {
padding-top: 130px;
@ -86,13 +126,30 @@ img {
/* --- Navbar --- */
.navbar-custom {
background-color: {{ site.navbar-col }};
background-color: {
{
site.navbar-col
}
}
;
border-bottom: 1px solid #EAEAEA;
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
{% if site.navbar-img %}
font-family: 'Open Sans',
'Helvetica Neue',
Helvetica,
Arial,
sans-serif;
{
% if site.navbar-img %
}
background-image: url({{ site.navbar-img }});
background-attachment: fixed;
{% endif %}
{
% endif %
}
}
.navbar-custom .nav li a {
@ -104,14 +161,27 @@ img {
.navbar-custom .navbar-brand,
.navbar-custom .nav li a {
font-weight: 800;
color: {{ site.navbar-text-col }};
color: {
{
site.navbar-text-col
}
}
;
}
.navbar-custom .navbar-brand:hover,
.navbar-custom .navbar-brand:focus ,
.navbar-custom .navbar-brand:focus,
.navbar-custom .nav li a:hover,
.navbar-custom .nav li a:focus {
color: {{ site.hover-col }};
color: {
{
site.hover-col
}
}
;
}
.navbar-custom .navbar-brand-logo {
@ -120,15 +190,18 @@ img {
-moz-transition: padding .5s ease-in-out;
transition: padding .5s ease-in-out;
}
.navbar-custom .navbar-brand-logo img {
height: 50px;
-webkit-transition: height .5s ease-in-out;
-moz-transition: height .5s ease-in-out;
transition: height .5s ease-in-out;
}
.navbar-custom.top-nav-short .navbar-brand-logo {
padding-top: 5px;
}
.navbar-custom.top-nav-short .navbar-brand-logo img {
height: 40px;
}
@ -136,9 +209,9 @@ img {
@media only screen and (min-width: 768px) {
.navbar-custom {
padding: 20px 0;
-webkit-transition: background .5s ease-in-out,padding .5s ease-in-out;
-moz-transition: background .5s ease-in-out,padding .5s ease-in-out;
transition: background .5s ease-in-out,padding .5s ease-in-out;
-webkit-transition: background .5s ease-in-out, padding .5s ease-in-out;
-moz-transition: background .5s ease-in-out, padding .5s ease-in-out;
transition: background .5s ease-in-out, padding .5s ease-in-out;
}
.navbar-custom.top-nav-short {
@ -152,7 +225,8 @@ img {
width: 50px;
margin-top: -25px;
}
.navbar-custom .avatar-container .avatar-img-border {
.navbar-custom .avatar-container .avatar-img-border {
width: 100%;
border-radius: 50%;
margin-left: -50%;
@ -161,13 +235,14 @@ img {
-webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .8);
-moz-box-shadow: 0 0 8px rgba(0, 0, 0, .8);
}
.navbar-custom .avatar-container .avatar-img {
.navbar-custom .avatar-container .avatar-img {
width: 100%;
border-radius: 50%;
display: block;
}
.navbar-custom.top-nav-expanded .avatar-container {
.navbar-custom.top-nav-expanded .avatar-container {
display: none;
}
@ -177,14 +252,14 @@ img {
margin-top: -50px;
}
.navbar-custom .avatar-container .avatar-img-border {
.navbar-custom .avatar-container .avatar-img-border {
width: 100%;
box-shadow: 1px 1px 2px rgba(0, 0, 0, .8);
-webkit-box-shadow: 1px 1px 2px rgba(0, 0, 0, .8);
-moz-box-shadow: 1px 1px 2px rgba(0, 0, 0, .8);
}
.navbar-custom .avatar-container .avatar-img {
.navbar-custom .avatar-container .avatar-img {
width: 100%;
}
}
@ -193,44 +268,61 @@ img {
.navbar-custom .nav .navlinks-container {
position: relative;
}
.navbar-custom .nav .navlinks-parent:after {
content: " \25BC";
}
.navbar-custom .nav .navlinks-children {
width: 100%;
display: none;
word-break: break-word;
}
.navbar-custom .nav .navlinks-container .navlinks-children a {
display: block;
padding: 10px;
padding-left: 30px;
background-color: {{ site.navbar-children-col }};
background-color: {
{
site.navbar-children-col
}
}
;
text-decoration: none !important;
border-width: 0 1px 1px 1px;
font-weight: normal;
}
@media only screen and (max-width: 767px) {
.navbar-custom .nav .navlinks-container.show-children {
background: rgba(0, 0, 0, 0.2);
}
.navbar-custom .nav .navlinks-container.show-children .navlinks-children {
display: block;
}
}
@media only screen and (min-width: 768px) {
.navbar-custom .nav .navlinks-container {
text-align: center;
}
.navbar-custom .nav .navlinks-container:hover {
background: rgba(0, 0, 0, 0.1);
}
.navbar-custom .nav .navlinks-container:hover .navlinks-children {
display: block;
}
.navbar-custom .nav .navlinks-children {
position: absolute;
}
.navbar-custom .nav .navlinks-container .navlinks-children a {
padding-left: 10px;
border: 1px solid #eaeaea;
@ -245,30 +337,58 @@ footer {
border-top: 1px #EAEAEA solid;
margin-top: 50px;
font-size: 14px;
background-color: {{ site.footer-col }};
{% if site.footer-img %}
background-color: {
{
site.footer-col
}
}
;
{
% if site.footer-img %
}
background-image: url({{ site.footer-img }});
background-attachment: fixed;
{% endif %}
{
% endif %
}
}
footer p.text-muted {
color: {{ site.footer-text-col }};
color: {
{
site.footer-text-col
}
}
;
}
footer a {
color: {{site.footer-link-col}};
color: {
{
site.footer-link-col
}
}
;
}
footer .list-inline {
margin: 0;
padding: 0;
}
footer .copyright {
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
text-align: center;
margin-bottom: 0;
}
footer .theme-by {
text-align: center;
margin: 10px 0 0;
@ -278,9 +398,11 @@ footer .theme-by {
footer {
padding: 50px 0;
}
footer .footer-links {
font-size: 18px;
}
footer .copyright {
font-size: 16px;
}
@ -311,18 +433,27 @@ footer .theme-by {
.post-preview a:focus,
.post-preview a:hover {
text-decoration: none;
color: {{ site.hover-col }};
color: {
{
site.hover-col
}
}
;
}
.post-preview .post-title {
font-size: 30px;
margin-top: 0;
}
.post-preview .post-subtitle {
margin: 0;
font-weight: 300;
margin-bottom: 10px;
}
.post-preview .post-meta,
.post-heading .post-meta {
color: #808080;
@ -330,16 +461,20 @@ footer .theme-by {
font-style: italic;
margin: 0 0 10px;
}
.post-preview .post-entry {
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
.post-entry-container {
display: inline-block;
width: 100%;
}
.post-entry {
width: 100%;
}
.post-image {
float: right;
height: 192px;
@ -347,14 +482,17 @@ footer .theme-by {
margin-top: -35px;
filter: grayscale(90%);
}
.post-image:hover {
filter: grayscale(0%);
}
.post-image img {
border-radius: 100px;
height: 192px;
width: 192px;
}
.post-preview .post-read-more {
font-weight: 800;
}
@ -375,14 +513,27 @@ footer .theme-by {
}
.blog-tags a {
color: {{ site.link-col }};
color: {
{
site.link-col
}
}
;
text-decoration: none;
padding: 0px 5px;
}
.blog-tags a:hover {
border-radius: 2px;
color: {{ site.hover-col }};
color: {
{
site.hover-col
}
}
;
background-color: #EEE;
}
@ -398,7 +549,9 @@ footer .theme-by {
}
@media only screen and (max-width: 500px) {
.post-image, .post-image img {
.post-image,
.post-image img {
height: 100px;
width: 100px;
}
@ -410,22 +563,26 @@ footer .theme-by {
float: left;
}
}
/* --- Post and page headers --- */
.intro-header {
margin: 80px 0 20px;
position: relative;
}
.intro-header.big-img {
background: no-repeat center center;
-webkit-background-size: cover;
-moz-background-size: cover;
background-size: cover;
-o-background-size: cover;
margin-top: 51px; /* The small navbar is 50px tall + 1px border */
margin-top: 51px;
/* The small navbar is 50px tall + 1px border */
margin-bottom: 35px;
}
.intro-header.big-img .big-img-transition {
.intro-header.big-img .big-img-transition {
position: absolute;
width: 100%;
height: 100%;
@ -439,23 +596,28 @@ footer .theme-by {
-moz-transition: opacity 1s linear;
transition: opacity 1s linear;
}
.intro-header .page-heading {
text-align: center;
}
.intro-header.big-img .page-heading,
.intro-header.big-img .post-heading {
padding: 100px 0;
color: #FFF;
text-shadow: 1px 1px 3px #000;
}
.intro-header .page-heading h1 {
margin-top: 0;
font-size: 50px;
}
.intro-header .post-heading h1 {
margin-top: 0;
font-size: 35px;
}
.intro-header .page-heading .page-subheading,
.intro-header .post-heading .post-subheading {
font-size: 27px;
@ -465,21 +627,26 @@ footer .theme-by {
font-weight: 300;
margin: 10px 0 0;
}
.intro-header .post-heading .post-subheading {
margin-bottom: 20px;
}
.intro-header.big-img .page-heading .page-subheading,
.intro-header.big-img .post-heading .post-subheading {
font-weight: 400;
}
.intro-header.big-img .page-heading hr {
box-shadow: 1px 1px 3px #000;
-webkit-box-shadow: 1px 1px 3px #000;
-moz-box-shadow: 1px 1px 3px #000;
}
.intro-header.big-img .post-heading .post-meta {
color: #EEE;
}
.intro-header.big-img .img-desc {
background: rgba(30, 30, 30, 0.6);
position: absolute;
@ -491,23 +658,30 @@ footer .theme-by {
bottom: 0;
display: none;
}
@media only screen and (min-width: 768px) {
.intro-header {
margin-top: 130px;
}
.intro-header.big-img {
margin-top: 91px; /* Full navbar is small navbar + 20px padding on each side when expanded */
margin-top: 91px;
/* Full navbar is small navbar + 20px padding on each side when expanded */
}
.intro-header.big-img .page-heading,
.intro-header.big-img .post-heading {
.intro-header.big-img .post-heading {
padding: 150px 0;
}
.intro-header .page-heading h1 {
font-size: 80px;
}
.intro-header .post-heading h1 {
font-size: 50px;
}
.intro-header.big-img .img-desc {
font-size: 14px;
}
@ -520,26 +694,32 @@ footer .theme-by {
padding: 20px 0;
box-shadow: 0 0 5px #AAA;
}
/* Many phones are 320 or 360px, so make sure images are a proper aspect ratio in those cases */
.header-section.has-img .intro-header.no-img {
display: none;
}
@media only screen and (max-width: 365px) {
.header-section.has-img .intro-header.no-img {
display: block;
}
.intro-header.big-img {
width: 100%;
height: 220px;
}
.intro-header.big-img .page-heading,
.intro-header.big-img .post-heading {
display: none;
}
.header-section.has-img .big-img {
margin-bottom: 0;
}
}
@media only screen and (max-width: 325px) {
.intro-header.big-img {
height: 200px;
@ -560,35 +740,39 @@ footer .theme-by {
#header-gh-btns {
margin-bottom: 15px;
}
@media only screen and (max-width: 500px) {
#header-gh-btns > iframe {
#header-gh-btns>iframe {
display: block;
margin-bottom: 5px;
}
}
/* --- custom layout css --- */
.intro-header .custom-heading
.intro-header .tags-heading,
.intro-header .custom-heading .intro-header .tags-heading,
.intro-header .categories-heading {
text-align: center;
}
.intro-header.big-img .custom-heading,
.intro-header.big-img .post-heading {
padding: 100px 0;
color: #FFF;
text-shadow: 1px 1px 3px #000;
}
.intro-header .custom-heading h1,
.intro-header .tags-heading h1,
.intro-header .categories-heading h1 {
margin-top: 0;
font-size: 50px;
}
.intro-header .post-heading h1 {
margin-top: 0;
font-size: 35px;
}
.intro-header .custom-heading .page-subheading,
.intro-header .post-heading .post-subheading {
font-size: 27px;
@ -598,21 +782,26 @@ footer .theme-by {
font-weight: 300;
margin: 10px 0 0;
}
.intro-header .post-heading .post-subheading {
margin-bottom: 20px;
}
.intro-header.big-img .custom-heading .page-subheading,
.intro-header.big-img .post-heading .post-subheading {
font-weight: 400;
}
.intro-header.big-img .custom-heading hr {
box-shadow: 1px 1px 3px #000;
-webkit-box-shadow: 1px 1px 3px #000;
-moz-box-shadow: 1px 1px 3px #000;
}
.intro-header.big-img .post-heading .post-meta {
color: #EEE;
}
.intro-header.big-img .img-desc {
background: rgba(30, 30, 30, 0.6);
position: absolute;
@ -624,26 +813,33 @@ footer .theme-by {
bottom: 0;
display: none;
}
@media only screen and (min-width: 768px) {
.intro-header {
margin-top: 130px;
}
.intro-header.big-img {
margin-top: 91px; /* Full navbar is small navbar + 20px padding on each side when expanded */
margin-top: 91px;
/* Full navbar is small navbar + 20px padding on each side when expanded */
}
.intro-header.big-img .custom-heading,
.intro-header.big-img .post-heading {
.intro-header.big-img .post-heading {
padding: 150px 0;
}
.intro-header .custom-heading h1,
.intro-header .tags-heading h1,
.intro-header .categories-heading h1 {
font-size: 80px;
text-align: center;
}
.intro-header .post-heading h1 {
font-size: 50px;
}
.intro-header.big-img .img-desc {
font-size: 14px;
}
@ -656,26 +852,32 @@ footer .theme-by {
padding: 20px 0;
box-shadow: 0 0 5px #AAA;
}
/* Many phones are 320 or 360px, so make sure images are a proper aspect ratio in those cases */
.header-section.has-img .intro-header.no-img {
display: none;
}
@media only screen and (max-width: 365px) {
.header-section.has-img .intro-header.no-img {
display: block;
}
.intro-header.big-img {
width: 100%;
height: 220px;
}
.intro-header.big-img .custom-heading,
.intro-header.big-img .post-heading {
display: none;
}
.header-section.has-img .big-img {
margin-bottom: 0;
}
}
@media only screen and (max-width: 325px) {
.intro-header.big-img {
height: 200px;
@ -696,16 +898,32 @@ footer .theme-by {
border-radius: 0;
color: #404040;
}
@media only screen and (min-width: 768px) {
.pager li a {
padding: 15px 25px;
}
}
.pager li a:hover,
.pager li a:focus {
color: #FFF;
border: 1px solid {{ site.hover-col }};
background-color: {{ site.hover-col }};
border: 1px solid {
{
site.hover-col
}
}
;
background-color: {
{
site.hover-col
}
}
;
}
.pager {
@ -717,7 +935,7 @@ footer .theme-by {
}
@media only screen and (min-width: 768px) {
.pager.blog-pager {
.pager.blog-pager {
margin-top: 10px;
}
}
@ -727,15 +945,18 @@ footer .theme-by {
table {
padding: 0;
}
table tr {
border-top: 1px solid #cccccc;
background-color: #ffffff;
margin: 0;
padding: 0;
}
table tr:nth-child(2n) {
background-color: #f8f8f8;
}
table tr th {
font-weight: bold;
border: 1px solid #cccccc;
@ -743,16 +964,19 @@ table tr th {
margin: 0;
padding: 6px 13px;
}
table tr td {
border: 1px solid #cccccc;
text-align: left;
margin: 0;
padding: 6px 13px;
}
table tr th :first-child,
table tr td :first-child {
margin-top: 0;
}
table tr th :last-child,
table tr td :last-child {
margin-bottom: 0;
@ -764,10 +988,14 @@ pre {
font-size: 16px;
line-height: 1.5em;
}
pre code {
white-space: pre;
}
pre.highlight, .highlight > pre, td.code pre {
pre.highlight,
.highlight>pre,
td.code pre {
background-color: #FAFAFA;
background-image: linear-gradient(#F9F9F9 50%, #FDFDFD 50%);
background-repeat: repeat;
@ -775,24 +1003,33 @@ pre.highlight, .highlight > pre, td.code pre {
background-position: 0px 10px;
border-left: 7px solid #444;
}
code table, code table td, code table th, code table tbody, code table tr,
code table,
code table td,
code table th,
code table tbody,
code table tr,
td.gutter pre {
padding: 0;
border: none;
background-color: #fff;
}
.highlight > pre {
.highlight>pre {
padding: 0;
}
.highlight > pre.highlight {
.highlight>pre.highlight {
padding: 9.5px;
}
td.code pre {
border-width: 0 0 0 2px;
border-style: solid;
border-color: #444;
border-radius: 0;
}
td.gutter {
padding-top: 3px;
}
@ -804,7 +1041,9 @@ td.gutter {
}
/* --- Notification boxes --- */
.box-note, .box-warning, .box-error {
.box-note,
.box-warning,
.box-error {
padding: 15px 15px 15px 10px;
margin: 20px 20px 20px 5px;
border: 1px solid #eee;
@ -829,11 +1068,13 @@ td.gutter {
/* Fix table border github gist snippets */
.gist, .gist-file table tr {
.gist,
.gist-file table tr {
border: unset;
}
.gist, .gist-file table tr td {
.gist,
.gist-file table tr td {
border: unset;
}
@ -871,26 +1112,3 @@ td.gutter {
font-style: italic;
font-size: 16px;
}
/** projects page */
#we-ride-httpsweridesocial::before {
content: "";
display: block;
height: 100px; /* fixed header height*/
margin: -100px 0 0; /* negative fixed header height */
}
#neoq-httpsgithubcomacaloiaroneoq::before {
content: "";
display: block;
height: 100px; /* fixed header height*/
margin: -100px 0 0; /* negative fixed header height */
}
#env-sample-sync-httpsgithubcomacaloiaroenv-sample-sync::before {
content: "";
display: block;
height: 100px; /* fixed header height*/
margin: -100px 0 0; /* negative fixed header height */
}