├── .gitattributes ├── .github ├── CODEOWNERS ├── dependabot.yml ├── release-drafter.yml └── workflows │ ├── docker-publish.yml │ ├── draft-release.yml │ ├── record.yml │ ├── release.yml │ ├── shellcheck.yml │ └── test.yml ├── Dockerfile ├── Gemfile ├── LICENSE ├── README.md ├── action.yml ├── bin ├── compare_expected_output ├── record_expected_output └── sync_expected_output.ps1 ├── entrypoint.sh └── test_projects ├── future-false ├── _config.yaml ├── _expected │ ├── 2020 │ │ └── 02 │ │ │ └── 13 │ │ │ └── the-future-is-looking-bright.html │ └── assets │ │ └── css │ │ └── style.css └── _posts │ ├── 2020-02-13-the-future-is-looking-bright.md │ └── 2022-03-01-we-live-in-hell.md ├── future-true ├── _config.yaml ├── _expected │ ├── 2020 │ │ └── 02 │ │ │ └── 13 │ │ │ └── the-future-is-looking-bright.html │ ├── 2022 │ │ └── 03 │ │ │ └── 01 │ │ │ └── we-live-in-hell.html │ └── assets │ │ └── css │ │ └── style.css └── _posts │ ├── 2020-02-13-the-future-is-looking-bright.md │ └── 2022-03-01-we-live-in-hell.md ├── jekyll-include-cache ├── _config.yml ├── _expected │ ├── assets │ │ └── css │ │ │ └── style.css │ └── index.html ├── _includes │ └── shirt.html └── index.md ├── mojombo ├── Gemfile ├── Gemfile.lock ├── README.md ├── _config.yaml ├── _expected │ ├── 2008 │ │ ├── 10 │ │ │ ├── 18 │ │ │ │ └── how-i-turned-down-300k.html │ │ │ └── 27 │ │ │ │ └── looking-back-on-selling-gravatar-to-automattic.html │ │ └── 11 │ │ │ ├── 17 │ │ │ └── blogging-like-a-hacker.html │ │ │ └── 03 │ │ │ └── how-to-meet-your-next-cofounder.html │ ├── 2009 │ │ └── 05 │ │ │ └── 19 │ │ │ └── the-git-parable.html │ ├── 2010 │ │ ├── 10 │ │ │ └── 18 │ │ │ │ └── optimize-for-happiness.html │ │ ├── 12 │ │ │ └── 11 │ │ │ │ └── designer-architect-developer.html │ │ ├── 05 │ │ │ └── 11 │ │ │ │ └── tomdoc-reasonable-ruby-documentation.html │ │ └── 08 │ │ │ └── 23 │ │ │ └── readme-driven-development.html │ ├── 2011 │ │ ├── 11 │ │ │ └── 22 │ │ │ │ └── open-source-everything.html │ │ ├── 03 │ │ │ └── 29 │ │ │ │ └── ten-lessons-from-githubs-first-year.html │ │ └── 05 │ │ │ └── 03 │ │ │ └── rejected-bio-from-the-setup.html │ ├── 2014 │ │ └── 04 │ │ │ └── 21 │ │ │ └── farewell-github-hello-immersive-computing.html │ ├── 2015 │ │ └── 06 │ │ │ └── 19 │ │ │ └── replicated.html │ ├── 2016 │ │ └── 11 │ │ │ └── 10 │ │ │ └── snyk.html │ ├── README.md │ ├── assets │ │ └── css │ │ │ └── style.css │ ├── atom.xml │ ├── css │ │ ├── screen.css │ │ └── syntax.css │ ├── images │ │ ├── posts │ │ │ └── 2016-11-10 │ │ │ │ └── breaches.png │ │ └── rss.png │ ├── index.html │ ├── pgp.txt │ └── random │ │ └── canvas_rotated_textfill.html ├── _layouts │ ├── default.html │ └── post.html ├── _posts │ ├── 2008-10-18-how-i-turned-down-300k.md │ ├── 2008-10-27-looking-back-on-selling-gravatar-to-automattic.md │ ├── 2008-11-03-how-to-meet-your-next-cofounder.md │ ├── 2008-11-17-blogging-like-a-hacker.md │ ├── 2009-05-19-the-git-parable.md │ ├── 2010-05-11-tomdoc-reasonable-ruby-documentation.md │ ├── 2010-08-23-readme-driven-development.md │ ├── 2010-10-18-optimize-for-happiness.md │ ├── 2010-12-11-designer-architect-developer.md │ ├── 2011-03-29-ten-lessons-from-githubs-first-year.md │ ├── 2011-05-03-rejected-bio-from-the-setup.md │ ├── 2011-11-22-open-source-everything.md │ ├── 2014-04-21-farewell-github-hello-immersive-computing.md │ ├── 2015-06-19-replicated.md │ └── 2016-11-10-snyk.md ├── atom.xml ├── css │ ├── screen.css │ └── syntax.css ├── images │ ├── posts │ │ └── 2016-11-10 │ │ │ └── breaches.png │ └── rss.png ├── index.html ├── pgp.txt └── random │ └── canvas_rotated_textfill.html ├── octicons ├── README.md ├── _config.yml └── _expected │ ├── README.md │ ├── assets │ └── css │ │ └── style.css │ └── index.html ├── readme ├── README.md ├── _config.yml └── _expected │ ├── README.md │ ├── assets │ └── css │ │ └── style.css │ └── index.html ├── simple ├── _config.yaml ├── _expected │ ├── assets │ │ └── css │ │ │ └── style.css │ └── index.html └── index.md └── themes ├── _config.yml ├── _expected ├── assets │ ├── css │ │ └── style.css │ ├── fonts │ │ ├── Noto-Sans-700 │ │ │ ├── Noto-Sans-700.eot │ │ │ ├── Noto-Sans-700.svg │ │ │ ├── Noto-Sans-700.ttf │ │ │ ├── Noto-Sans-700.woff │ │ │ └── Noto-Sans-700.woff2 │ │ ├── Noto-Sans-700italic │ │ │ ├── Noto-Sans-700italic.eot │ │ │ ├── Noto-Sans-700italic.svg │ │ │ ├── Noto-Sans-700italic.ttf │ │ │ ├── Noto-Sans-700italic.woff │ │ │ └── Noto-Sans-700italic.woff2 │ │ ├── Noto-Sans-italic │ │ │ ├── Noto-Sans-italic.eot │ │ │ ├── Noto-Sans-italic.svg │ │ │ ├── Noto-Sans-italic.ttf │ │ │ ├── Noto-Sans-italic.woff │ │ │ └── Noto-Sans-italic.woff2 │ │ └── Noto-Sans-regular │ │ │ ├── Noto-Sans-regular.eot │ │ │ ├── Noto-Sans-regular.svg │ │ │ ├── Noto-Sans-regular.ttf │ │ │ ├── Noto-Sans-regular.woff │ │ │ └── Noto-Sans-regular.woff2 │ ├── img │ │ └── logo.png │ └── js │ │ └── scale.fix.js └── index.html └── index.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Default PR reviewers 2 | * @actions/pages 3 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "bundler" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | groups: 8 | non-breaking-changes: 9 | update-types: [minor, patch] 10 | 11 | - package-ecosystem: "github-actions" 12 | directory: "/" 13 | schedule: 14 | interval: "weekly" 15 | groups: 16 | non-breaking-changes: 17 | update-types: [minor, patch] 18 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name-template: 'v$RESOLVED_VERSION' 3 | tag-template: 'v$RESOLVED_VERSION' 4 | template: | 5 | # Changelog 6 | 7 | $CHANGES 8 | 9 | See details of [all code changes](https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION) since previous release. 10 | categories: 11 | - title: '🚀 Features' 12 | labels: 13 | - 'feature' 14 | - 'enhancement' 15 | - title: '🐛 Bug Fixes' 16 | labels: 17 | - 'fix' 18 | - 'bugfix' 19 | - 'bug' 20 | - title: '🧰 Maintenance' 21 | labels: 22 | - 'infrastructure' 23 | - 'automation' 24 | - 'documentation' 25 | - title: '🏎 Performance' 26 | label: 'performance' 27 | change-template: '- $TITLE @$AUTHOR (#$NUMBER)' 28 | version-resolver: 29 | major: 30 | labels: 31 | - 'type: breaking' 32 | minor: 33 | labels: 34 | - 'type: enhancement' 35 | patch: 36 | labels: 37 | - 'type: bug' 38 | - 'type: maintenance' 39 | - 'type: documentation' 40 | default: patch 41 | -------------------------------------------------------------------------------- /.github/workflows/docker-publish.yml: -------------------------------------------------------------------------------- 1 | name: Docker 2 | 3 | # This workflow uses actions that are not certified by GitHub. 4 | # They are provided by a third-party and are governed by 5 | # separate terms of service, privacy policy, and support 6 | # documentation. 7 | 8 | on: 9 | push: 10 | branches: 11 | - 'main' 12 | - 'feature-*' 13 | tags: 14 | - 'v*' 15 | env: 16 | # Use docker.io for Docker Hub if empty 17 | REGISTRY: ghcr.io 18 | # github.repository as / 19 | IMAGE_NAME: ${{ github.repository }} 20 | 21 | jobs: 22 | build: 23 | runs-on: ubuntu-latest 24 | 25 | steps: 26 | - name: Checkout repository 27 | uses: actions/checkout@v4 28 | 29 | # Login against a Docker registry except on PR 30 | # https://github.com/docker/login-action 31 | - name: Log into registry ${{ env.REGISTRY }} 32 | uses: docker/login-action@v3 33 | with: 34 | registry: ${{ env.REGISTRY }} 35 | username: ${{ github.actor }} 36 | password: ${{ secrets.GITHUB_TOKEN }} 37 | - name: Generate Image Tags 38 | id: generate-image-tags 39 | run: | 40 | # Generate tags for the image 41 | if [[ "${{ github.ref_name }}" == "main" ]]; then 42 | tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest 43 | else 44 | tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }} 45 | fi 46 | echo "tags=$tags" >> $GITHUB_OUTPUT 47 | - name: Extract Docker metadata 48 | id: meta 49 | uses: docker/metadata-action@v5 50 | with: 51 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} 52 | 53 | # Build and push Docker image with Buildx (don't push on PR) 54 | # https://github.com/docker/build-push-action 55 | - name: Build and push Docker image 56 | uses: docker/build-push-action@v6 57 | with: 58 | context: . 59 | file: Dockerfile 60 | push: true 61 | tags: ${{ steps.generate-image-tags.outputs.tags }} 62 | labels: ${{ steps.meta.outputs.labels }} 63 | -------------------------------------------------------------------------------- /.github/workflows/draft-release.yml: -------------------------------------------------------------------------------- 1 | name: Draft release 2 | on: 3 | push: 4 | branches: 5 | - main 6 | 7 | permissions: 8 | contents: write 9 | 10 | jobs: 11 | draft-release: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: release-drafter/release-drafter@3f0f87098bd6b5c5b9a36d49c41d998ea58f9348 16 | env: 17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 18 | -------------------------------------------------------------------------------- /.github/workflows/record.yml: -------------------------------------------------------------------------------- 1 | name: Record Expected 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | env: 7 | # Use docker.io for Docker Hub if empty 8 | REGISTRY: ghcr.io 9 | # github.repository as / 10 | IMAGE_NAME: ${{ github.repository }} 11 | 12 | jobs: 13 | resolve-image-tag: 14 | runs-on: ubuntu-latest 15 | outputs: 16 | tag: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.regex-match.outputs.group1 }} 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v4 20 | - name: Grep action.yaml content 21 | id: grep-image-content 22 | run: | 23 | image=$(grep -E "jekyll-build-pages.*\'" action.yml) 24 | echo "image=$image" >> $GITHUB_OUTPUT 25 | - uses: actions-ecosystem/action-regex-match@v2 26 | id: regex-match 27 | with: 28 | text: ${{ steps.grep-image-content.outputs.image }} 29 | regex: "jekyll-build-pages:(.*)'" 30 | 31 | test-builds: 32 | needs: resolve-image-tag 33 | runs-on: ubuntu-latest 34 | strategy: 35 | matrix: 36 | test: 37 | - simple 38 | - readme 39 | - octicons 40 | - mojombo 41 | - themes 42 | - jekyll-include-cache 43 | - future-false 44 | - future-true 45 | steps: 46 | - name: Checkout repository 47 | uses: actions/checkout@v4 48 | - name: Build local docker image 49 | uses: docker/build-push-action@v6 50 | with: 51 | context: . 52 | file: Dockerfile 53 | tags: ${{ needs.resolve-image-tag.outputs.tag }} 54 | 55 | - name: Build ${{ matrix.test }} Project 56 | uses: ./ 57 | with: 58 | source: ./test_projects/${{ matrix.test }} 59 | destination: ./test_projects/${{ matrix.test }}/_expected 60 | build_revision: JEKYLL_BUILD_REVISION 61 | token: ${{ secrets.GITHUB_TOKEN }} 62 | 63 | - name: Archive ${{ matrix.test }} Project 64 | uses: actions/upload-artifact@v4 65 | with: 66 | name: ${{ matrix.test }} 67 | path: ./test_projects/${{ matrix.test }}/_expected 68 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | release: 4 | types: [released] 5 | workflow_dispatch: 6 | inputs: 7 | TAG_NAME: 8 | description: "Tag name that the major tag will point to" 9 | required: true 10 | 11 | env: 12 | TAG_NAME: ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }} 13 | REGISTRY: ghcr.io 14 | IMAGE_NAME: ${{ github.repository }} 15 | 16 | permissions: 17 | contents: write 18 | 19 | jobs: 20 | verify_release: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - name: Checkout repository 24 | uses: actions/checkout@v4 25 | - name: Grep action.yaml content 26 | id: grep-image-content 27 | run: | 28 | image=$(grep -E "jekyll-build-pages.*\'" action.yml) 29 | echo "image=$image" >> $GITHUB_OUTPUT 30 | - uses: actions-ecosystem/action-regex-match@v2 31 | id: regex-match 32 | with: 33 | text: ${{ steps.grep-image-content.outputs.image }} 34 | regex: "jekyll-build-pages:(.*)'" 35 | - name: Version match 36 | run: | 37 | if [ "${{ steps.regex-match.outputs.group1 }}" != "${{ env.TAG_NAME }}" ]; then 38 | echo "version mismatch. action.yaml with version ${{ steps.regex-match.outputs.group1 }} Tag version ${{ env.TAG_NAME }}"; 39 | exit 1 40 | fi 41 | - name: Verify image published 42 | run: docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.TAG_NAME }} 43 | 44 | update_tag: 45 | needs: verify_release 46 | name: Update the major tag to include the ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }} changes 47 | environment: 48 | # Note: this environment is protected 49 | name: Release 50 | runs-on: ubuntu-latest 51 | outputs: 52 | major_tag: ${{ steps.update-major-tag.outputs.major-tag }} 53 | steps: 54 | - name: Update the ${{ env.TAG_NAME }} major tag 55 | id: update-major-tag 56 | uses: actions/publish-action@v0.3.0 57 | with: 58 | source-tag: ${{ env.TAG_NAME }} 59 | -------------------------------------------------------------------------------- /.github/workflows/shellcheck.yml: -------------------------------------------------------------------------------- 1 | name: 'ShellCheck' 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - '**.sh' 7 | # this is too wide but will cover shell scripts without an extension in that folder 8 | - 'bin/*' 9 | 10 | jobs: 11 | shellcheck: 12 | runs-on: ubuntu-latest 13 | env: 14 | SHELLCHECK_OPTS: -s bash 15 | steps: 16 | - name: Checkout repository 17 | uses: actions/checkout@v4 18 | 19 | - name: Run ShellCheck 20 | uses: ludeeus/action-shellcheck@master 21 | with: 22 | version: v0.8.0 23 | format: tty 24 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: "Test" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | env: 9 | # Use docker.io for Docker Hub if empty 10 | REGISTRY: ghcr.io 11 | # github.repository as / 12 | IMAGE_NAME: ${{ github.repository }} 13 | 14 | jobs: 15 | resolve-image-tag: 16 | runs-on: ubuntu-latest 17 | outputs: 18 | tag: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.regex-match.outputs.group1 }} 19 | steps: 20 | - name: Checkout repository 21 | uses: actions/checkout@v4 22 | - name: Grep action.yaml content 23 | id: grep-image-content 24 | run: | 25 | image=$(grep -E "jekyll-build-pages.*\'" action.yml) 26 | echo "image=$image" >> $GITHUB_OUTPUT 27 | - uses: actions-ecosystem/action-regex-match@v2 28 | id: regex-match 29 | with: 30 | text: ${{ steps.grep-image-content.outputs.image }} 31 | regex: "jekyll-build-pages:(.*)'" 32 | 33 | test-builds: 34 | needs: resolve-image-tag 35 | runs-on: ubuntu-latest 36 | strategy: 37 | matrix: 38 | test: 39 | - simple 40 | - readme 41 | - octicons 42 | - mojombo 43 | - themes 44 | - jekyll-include-cache 45 | - future-false 46 | - future-true 47 | steps: 48 | - name: Checkout repository 49 | uses: actions/checkout@v4 50 | - name: Build local docker image 51 | uses: docker/build-push-action@v6 52 | with: 53 | context: . 54 | file: Dockerfile 55 | tags: ${{ needs.resolve-image-tag.outputs.tag }} 56 | - name: Test ${{ matrix.test }} Project 57 | uses: ./ 58 | with: 59 | source: ./test_projects/${{ matrix.test }} 60 | destination: ./test_projects/${{ matrix.test }}/_site 61 | build_revision: JEKYLL_BUILD_REVISION 62 | token: ${{ secrets.GITHUB_TOKEN }} 63 | 64 | - name: Verify output 65 | run: | 66 | ./bin/compare_expected_output ./test_projects/${{matrix.test}} 67 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG RUBY_VERSION=3.3 2 | FROM ruby:$RUBY_VERSION-slim 3 | 4 | RUN apt-get update \ 5 | && apt-get install -y \ 6 | build-essential \ 7 | git \ 8 | locales \ 9 | nodejs 10 | 11 | COPY Gemfile Gemfile 12 | 13 | RUN NOKOGIRI_USE_SYSTEM_LIBRARIES=true bundle install 14 | 15 | RUN \ 16 | echo "en_US UTF-8" > /etc/locale.gen && \ 17 | locale-gen en-US.UTF-8 18 | ENV LANG en_US.UTF-8 19 | ENV LANGUAGE en_US.UTF-8 20 | ENV LC_ALL en_US.UTF-8 21 | 22 | COPY entrypoint.sh /entrypoint.sh 23 | 24 | ENTRYPOINT ["/entrypoint.sh"] 25 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } 6 | 7 | # Manage our dependency on the version of the github-pages gem here. 8 | gem "github-pages", "= 232" 9 | 10 | # Explicitly include this gem here. 11 | # It is not directly included in the github-pages gem list of dependencies, 12 | # even though it is included in the original GitHub Pages build infrastructure. 13 | gem "jekyll-include-cache", "= 0.2.1" 14 | gem "jekyll-octicons", "~> 14.2" 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 GitHub, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jekyll-build-pages 2 | 3 | A simple GitHub Action for producing Jekyll build artifacts compatible with GitHub Pages. 4 | 5 | ## Scope 6 | 7 | This is used along with [`actions/deploy-pages`](https://github.com/actions/deploy-pages) as part of the official support for building Pages with Actions (currently in public beta for public repositories). 8 | 9 | ## Usage 10 | 11 | A basic Pages deployment workflow with the `jekyll-build-pages` action looks like this. 12 | 13 | ```yaml 14 | name: Build Jekyll site 15 | on: 16 | push: 17 | branches: ["main"] 18 | permissions: 19 | contents: read 20 | pages: write 21 | id-token: write 22 | jobs: 23 | build: 24 | runs-on: ubuntu-latest 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@v4 28 | - name: Setup Pages 29 | uses: actions/configure-pages@v5 30 | - name: Build 31 | uses: actions/jekyll-build-pages@v1 32 | - name: Upload artifact 33 | uses: actions/upload-pages-artifact@v3 34 | deploy: 35 | runs-on: ubuntu-latest 36 | needs: build 37 | steps: 38 | - name: Deploy to GitHub Pages 39 | id: deployment 40 | uses: actions/deploy-pages@v4 41 | environment: 42 | name: github-pages 43 | url: ${{ steps.deployment.outputs.page_url }} 44 | ``` 45 | 46 | To write to a different destination directory, match the inputs of both the `jekyll-build-pages` and [`upload-pages-artifact`](https://github.com/actions/upload-pages-artifact) actions. 47 | 48 | ```yaml 49 | steps: 50 | - name: Build 51 | uses: actions/jekyll-build-pages@v1 52 | with: 53 | destination: "./output" 54 | - name: Upload artifact 55 | uses: actions/upload-pages-artifact@v3 56 | with: 57 | path: "./output" 58 | ``` 59 | 60 | ### Action inputs 61 | 62 | | Input | Default | Description | 63 | |-------|---------|-------------| 64 | | `source` | `./` | The directory to build from | 65 | | `destination` | `./_site` | The directory to write output into
(this should match the `path` input of the [`actions/upload-pages-artifact`](https://github.com/actions/upload-pages-artifact) action) | 66 | | `future` | `false` | If `true`, writes content dated in the future | 67 | | `build_revision` | `$GITHUB_SHA` | The SHA-1 of the Git commit for which the build is running | 68 | | `verbose` | `false` | If `true`, prints verbose output in logs | 69 | | `token` | `$GITHUB_TOKEN` | The GitHub token used to authenticate API requests | 70 | 71 | ## Release instructions 72 | 73 | In order to release a new version of this Action: 74 | 75 | 1. Locate the semantic version of the [upcoming release][release-list] (a draft is maintained by the [`draft-release` workflow][draft-release]). 76 | 77 | 2. Prepare a pull request to update [`action.yml`][action.yml] to reference the incoming version, get it approved, and merge it into the `main` branch. 78 | 79 | 3. Publish the draft release **as a pre-release** from the `main` branch with semantic version as the tag name, _with_: 80 | - the checkbox to publish to the GitHub Marketplace checked :ballot_box_with_check: 81 | - :warning: _AND_ the checkbox to **Set as a pre-release** checked. :ballot_box_with_check: 82 | 83 | 4. This will kick off a [Docker publishing workflow][docker-publish] for the newly created tag. Check the [associated workflow run list][docker-publish-workflow-runs] to verify the new Docker image is created successfully before moving on to the next step. 84 | 85 | 5. After the Docker image has been created with the new tag, find that [same pre-release][release-list] and edit it. Update it with the checkbox to **Set as the latest release** checked :ballot_box_with_check: and then publish it again. 86 | 87 | 6. After publishing it as the latest release, the [`release` workflow][release] will automatically run to create/update the corresponding the major version tag such as `v1`. 88 | 89 | ⚠️ Environment approval is required. Check the [Release workflow run list][release-workflow-runs]. 90 | 91 | ## License 92 | 93 | The scripts and documentation in this project are released under the [MIT License](LICENSE). 94 | 95 | 96 | [release-list]: https://github.com/actions/jekyll-build-pages/releases 97 | [draft-release]: .github/workflows/draft-release.yml 98 | [docker-publish]: .github/workflows/docker-publish.yml 99 | [release]: .github/workflows/release.yml 100 | [docker-publish-workflow-runs]: https://github.com/actions/jekyll-build-pages/actions/workflows/docker-publish.yml 101 | [release-workflow-runs]: https://github.com/actions/jekyll-build-pages/actions/workflows/release.yml 102 | [action.yml]: https://github.com/actions/jekyll-build-pages/blob/649f5d3c2b2462620c8945f034200e431ceddd29/action.yml#LL31C54-L31C60 103 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Build Jekyll for GitHub Pages' 2 | description: 'A simple GitHub Action for producing Jekyll build artifacts compatible with GitHub Pages' 3 | author: 'GitHub' 4 | inputs: 5 | source: 6 | description: 'Directory where the source files reside.' 7 | required: false 8 | default: ./ 9 | destination: 10 | description: 'Output directory of the build. Although it can be nested inside the source, it cannot be the same as the source directory.' 11 | required: false 12 | default: ./_site 13 | future: 14 | description: 'Publishes posts with a future date. When set to true, the build is made with the --future option which overrides the future option that may be set in a Jekyll configuration file.' 15 | required: false 16 | default: false 17 | build_revision: 18 | description: 'The SHA-1 of the git commit for which the build is running. Default to GITHUB_SHA.' 19 | required: false 20 | default: ${{ github.sha }} 21 | verbose: 22 | description: 'Verbose output' 23 | required: false 24 | default: true 25 | token: 26 | description: 'GitHub token' 27 | required: true 28 | default: ${{ github.token }} 29 | runs: 30 | using: 'docker' 31 | image: 'docker://ghcr.io/actions/jekyll-build-pages:v1.0.13' 32 | -------------------------------------------------------------------------------- /bin/compare_expected_output: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env ruby 2 | 3 | require "pathname" 4 | require "shellwords" 5 | 6 | project_path = ARGV[0] 7 | 8 | Dir.chdir(project_path) 9 | 10 | expected_files = Dir["_expected/**/*"].select { |path| File.file?(path) }.map { |path| Pathname.new(path).relative_path_from("_expected").to_s } 11 | actual_files = Dir["_site/**/*"].select { |path| File.file?(path) }.map { |path| Pathname.new(path).relative_path_from("_site").to_s } 12 | 13 | differences = [] 14 | 15 | expected_files.each do |expected_file| 16 | if actual_files.include?(expected_file) 17 | diff = `diff #{Shellwords.escape(File.join("_expected", expected_file))} #{Shellwords.escape(File.join("_site", expected_file))}` 18 | if !$?.success? 19 | differences << "Expected output of #{expected_file} differs:\n#{diff}" 20 | end 21 | else 22 | differences << "Missing expected file: #{expected_file}" 23 | end 24 | end 25 | 26 | unexpected_files = actual_files - expected_files 27 | unexpected_files.each do |unexpected_file| 28 | differences << "Unexpected file: #{unexpected_file}" 29 | end 30 | 31 | if !differences.empty? 32 | STDERR.puts "Differences between expected and actual outputs:" 33 | differences.each { |diff| STDERR.puts(diff) } 34 | exit(1) 35 | end 36 | -------------------------------------------------------------------------------- /bin/record_expected_output: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env sh 2 | 3 | if [ "local" = "$1" ]; then 4 | export JEKYLL_ENV=production 5 | export PAGES_REPO_NWO=actions/jekyll-build-pages 6 | export JEKYLL_BUILD_REVISION=JEKYLL_BUILD_REVISION 7 | 8 | for dir in test_projects/* 9 | do 10 | bundle exec github-pages build --verbose -s "test_projects/${dir}" -d "test_projects/${dir}/_expected" 11 | done 12 | else 13 | act -b -s GITHUB_TOKEN -j record-expected-output 14 | fi 15 | -------------------------------------------------------------------------------- /bin/sync_expected_output.ps1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pwsh 2 | #Requires -Version 7.2 3 | 4 | <# 5 | .SYNOPSIS 6 | Trigger the workflow that records the tests expected outputs, wait for its execution to finish, 7 | then bring back those results locally. 8 | 9 | .DESCRIPTION 10 | This script is meant to run locally outside of Actions. It relies on `gh` and `git`. 11 | #> 12 | 13 | # Get the repository's path (ps1 extension on the script is required for PSScriptRoot to be available 🤦) 14 | $repositoryPath = Resolve-Path (Join-Path $PSScriptRoot '..') 15 | 16 | # Get the test_project's path 17 | $testProjectsPath = Resolve-Path (Join-Path $PSScriptRoot '../test_projects') 18 | 19 | # 20 | # Utilities 21 | # 22 | 23 | # Run a command and validate it returned a 0 exit code 24 | function Invoke-Command { 25 | param ( 26 | [ScriptBlock] $Command 27 | ) 28 | 29 | & $Command 30 | if ($LASTEXITCODE -ne 0) { 31 | Write-Error "Command failed: $Command" 32 | throw 33 | } 34 | } 35 | 36 | # Get the current git ref name 37 | function Get-GitRef { 38 | $commitId = Invoke-Command { & git -C $repositoryPath rev-parse --abbrev-ref HEAD } 39 | $commitId.Trim() 40 | } 41 | 42 | # Create a temp folder and return its path 43 | function New-TemporaryFolder { 44 | $path = Join-Path ([System.IO.Path]::GetTempPath()) ([System.Guid]::NewGuid()) 45 | New-Item -ItemType 'Directory' -Path $path | Out-Null 46 | $path 47 | } 48 | 49 | # 50 | # Main 51 | # 52 | 53 | # Init 54 | Set-StrictMode -version 'Latest' 55 | $ErrorActionPreference = 'Stop' 56 | 57 | # Get git ref name 58 | $ref = Get-GitRef 59 | 60 | # Run the workflow 61 | Write-Host 'Queue workflow' 62 | $workflow = 'record.yml' 63 | Invoke-Command { & gh workflow run $workflow --ref $ref | Out-Null } 64 | 65 | # Wait for a few seconds for the workflow to get created 66 | Write-Host 'Wait a few seconds...' 67 | Start-Sleep -Seconds 5 68 | 69 | # Lookup the run id (it is not perfect because of the APIs...) 70 | Write-Host 'Lookup run id' 71 | $runId = Invoke-Command { & gh run list --workflow $workflow --branch $ref --limit 1 --json databaseId --jq '.[].databaseId' } 72 | 73 | # Wait for the workflow to finish 74 | Write-Host "Wait for workflow $runId to complete" 75 | Invoke-Command { & gh run watch $runId --exit-status } 76 | 77 | # Download the artifacts in a temp folder 78 | Write-Host 'Download artifacts' 79 | $tempFolder = New-TemporaryFolder 80 | Invoke-Command { & gh run download $runId --dir $tempFolder } 81 | 82 | # Iterate over the test projects 83 | Get-ChildItem -Path $testProjectsPath -Directory | ForEach-Object { 84 | # Construct the artifact path and make sure a matching artifact is found 85 | $artifactPath = Join-Path $tempFolder $_.BaseName 86 | if (Test-Path $artifactPath -PathType 'Container') { 87 | # Copy artifact to the expected output folder 88 | $destinationPath = Join-Path $testProjectsPath $_.BaseName '_expected' 89 | Copy-Item -Path (Join-Path $artifactPath '*') -Destination $destinationPath -Recurse -Force | Out-Null 90 | } 91 | 92 | # Ignore test project 93 | else { 94 | Write-Warning "Unable to find artifact for test project $($_.BaseName)" 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #################################################################################################### 4 | # 5 | # Calls github-pages executable to build the site using allowed plugins and supported configuration 6 | # 7 | #################################################################################################### 8 | 9 | SOURCE_DIRECTORY=${GITHUB_WORKSPACE}/$INPUT_SOURCE 10 | DESTINATION_DIRECTORY=${GITHUB_WORKSPACE}/$INPUT_DESTINATION 11 | PAGES_GEM_HOME=$BUNDLE_APP_CONFIG 12 | GITHUB_PAGES_BIN=$PAGES_GEM_HOME/bin/github-pages 13 | 14 | # Check if Gemfile's dependencies are satisfied or print a warning 15 | if test -e "$SOURCE_DIRECTORY/Gemfile" && ! bundle check --dry-run --gemfile "$SOURCE_DIRECTORY/Gemfile"; then 16 | echo "::warning::The github-pages gem can't satisfy your Gemfile's dependencies. If you want to use a different Jekyll version or need additional dependencies, consider building Jekyll site with GitHub Actions: https://jekyllrb.com/docs/continuous-integration/github-actions/" 17 | fi 18 | 19 | # Set environment variables required by supported plugins 20 | export JEKYLL_ENV="production" 21 | export JEKYLL_GITHUB_TOKEN=$INPUT_TOKEN 22 | export PAGES_REPO_NWO=$GITHUB_REPOSITORY 23 | export JEKYLL_BUILD_REVISION=$INPUT_BUILD_REVISION 24 | export PAGES_API_URL=$GITHUB_API_URL 25 | 26 | # Set verbose flag 27 | if [ "$INPUT_VERBOSE" = 'true' ]; then 28 | VERBOSE='--verbose' 29 | else 30 | VERBOSE='' 31 | fi 32 | 33 | # Set future flag 34 | if [ "$INPUT_FUTURE" = 'true' ]; then 35 | FUTURE='--future' 36 | else 37 | FUTURE='' 38 | fi 39 | 40 | { cd "$PAGES_GEM_HOME" || { echo "::error::pages gem not found"; exit 1; }; } 41 | 42 | # Run the command, capturing the output 43 | build_output="$($GITHUB_PAGES_BIN build "$VERBOSE" "$FUTURE" --source "$SOURCE_DIRECTORY" --destination "$DESTINATION_DIRECTORY")" 44 | 45 | # Capture the exit code 46 | exit_code=$? 47 | 48 | if [ $exit_code -ne 0 ]; then 49 | # Remove the newlines from the build_output as annotation not support multiline 50 | error=$(echo "$build_output" | tr '\n' ' ' | tr -s ' ') 51 | echo "::error::$error" 52 | else 53 | # Display the build_output directly 54 | echo "$build_output" 55 | fi 56 | 57 | # Exit with the captured exit code 58 | exit $exit_code 59 | -------------------------------------------------------------------------------- /test_projects/future-false/_config.yaml: -------------------------------------------------------------------------------- 1 | time: 2022-02-02 02:02:02 2 | timezone: America/New_York 3 | -------------------------------------------------------------------------------- /test_projects/future-false/_expected/2020/02/13/the-future-is-looking-bright.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | The Future is Looking Bright! | jekyll-build-pages 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
41 | 42 |

jekyll-build-pages

43 | 44 | 45 |

Everything’s coming up Milhouse.

46 | 47 | 48 | 49 | 52 | 53 |
54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /test_projects/future-false/_posts/2020-02-13-the-future-is-looking-bright.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: The Future is Looking Bright! 3 | --- 4 | 5 | Everything's coming up Milhouse. 6 | -------------------------------------------------------------------------------- /test_projects/future-false/_posts/2022-03-01-we-live-in-hell.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: We Live In Hell 3 | --- 4 | 5 | And it's not even the cool hell that \[redacted\] are afraid of. 😭 6 | -------------------------------------------------------------------------------- /test_projects/future-true/_config.yaml: -------------------------------------------------------------------------------- 1 | time: 2022-02-02 02:02:02 2 | timezone: America/New_York 3 | future: true 4 | -------------------------------------------------------------------------------- /test_projects/future-true/_expected/2020/02/13/the-future-is-looking-bright.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | The Future is Looking Bright! | jekyll-build-pages 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
41 | 42 |

jekyll-build-pages

43 | 44 | 45 |

Everything’s coming up Milhouse.

46 | 47 | 48 | 49 | 52 | 53 |
54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /test_projects/future-true/_expected/2022/03/01/we-live-in-hell.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | We Live In Hell | jekyll-build-pages 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
41 | 42 |

jekyll-build-pages

43 | 44 | 45 |

And it’s not even the cool hell that [redacted] are afraid of. 😭

46 | 47 | 48 | 49 | 52 | 53 |
54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /test_projects/future-true/_posts/2020-02-13-the-future-is-looking-bright.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: The Future is Looking Bright! 3 | --- 4 | 5 | Everything's coming up Milhouse. 6 | -------------------------------------------------------------------------------- /test_projects/future-true/_posts/2022-03-01-we-live-in-hell.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: We Live In Hell 3 | --- 4 | 5 | And it's not even the cool hell that \[redacted\] are afraid of. 😭 6 | -------------------------------------------------------------------------------- /test_projects/jekyll-include-cache/_config.yml: -------------------------------------------------------------------------------- 1 | plugins: 2 | - jekyll-include-cache 3 | -------------------------------------------------------------------------------- /test_projects/jekyll-include-cache/_expected/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | jekyll-build-pages | A simple GitHub Action for producing Jekyll build artifacts compatible with GitHub Pages. 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
40 | 41 |

jekyll-build-pages

42 | 43 | 44 |
45 |
46 | 47 |

Buy our red shirt in medium!

48 | 49 | 50 | 51 | 52 | 55 | 56 |
57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /test_projects/jekyll-include-cache/_includes/shirt.html: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | Buy our {{ include.color }} shirt in {{ include.size }}! 5 | 6 | -------------------------------------------------------------------------------- /test_projects/jekyll-include-cache/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | {% include_cached shirt.html size="medium" color="red" %} 5 | 6 | -------------------------------------------------------------------------------- /test_projects/mojombo/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gem 'github-pages', group: :jekyll_plugins 3 | -------------------------------------------------------------------------------- /test_projects/mojombo/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | activesupport (4.2.7) 5 | i18n (~> 0.7) 6 | json (~> 1.7, >= 1.7.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.3, >= 0.3.4) 9 | tzinfo (~> 1.1) 10 | addressable (2.4.0) 11 | coffee-script (2.4.1) 12 | coffee-script-source 13 | execjs 14 | coffee-script-source (1.10.0) 15 | colorator (1.1.0) 16 | concurrent-ruby (1.1.10) 17 | ethon (0.9.1) 18 | ffi (>= 1.3.0) 19 | execjs (2.7.0) 20 | faraday (0.9.2) 21 | multipart-post (>= 1.2, < 3) 22 | ffi (1.9.14) 23 | forwardable-extended (2.6.0) 24 | gemoji (2.1.0) 25 | github-pages (102) 26 | activesupport (= 4.2.7) 27 | github-pages-health-check (= 1.2.0) 28 | jekyll (= 3.3.0) 29 | jekyll-coffeescript (= 1.0.1) 30 | jekyll-feed (= 0.7.2) 31 | jekyll-gist (= 1.4.0) 32 | jekyll-github-metadata (= 2.2.0) 33 | jekyll-mentions (= 1.2.0) 34 | jekyll-paginate (= 1.1.0) 35 | jekyll-redirect-from (= 0.11.0) 36 | jekyll-sass-converter (= 1.3.0) 37 | jekyll-seo-tag (= 2.0.0) 38 | jekyll-sitemap (= 0.11.0) 39 | jekyll-swiss (= 0.4.0) 40 | jemoji (= 0.7.0) 41 | kramdown (= 1.11.1) 42 | liquid (= 3.0.6) 43 | listen (= 3.0.6) 44 | mercenary (~> 0.3) 45 | minima (= 2.0.0) 46 | rouge (= 1.11.1) 47 | terminal-table (~> 1.4) 48 | github-pages-health-check (1.2.0) 49 | addressable (~> 2.3) 50 | net-dns (~> 0.8) 51 | octokit (~> 4.0) 52 | public_suffix (~> 1.4) 53 | typhoeus (~> 0.7) 54 | html-pipeline (2.4.2) 55 | activesupport (>= 2) 56 | nokogiri (>= 1.4) 57 | i18n (0.9.5) 58 | concurrent-ruby (~> 1.0) 59 | jekyll (3.3.0) 60 | addressable (~> 2.4) 61 | colorator (~> 1.0) 62 | jekyll-sass-converter (~> 1.0) 63 | jekyll-watch (~> 1.1) 64 | kramdown (~> 1.3) 65 | liquid (~> 3.0) 66 | mercenary (~> 0.3.3) 67 | pathutil (~> 0.9) 68 | rouge (~> 1.7) 69 | safe_yaml (~> 1.0) 70 | jekyll-coffeescript (1.0.1) 71 | coffee-script (~> 2.2) 72 | jekyll-feed (0.7.2) 73 | jekyll-gist (1.4.0) 74 | octokit (~> 4.2) 75 | jekyll-github-metadata (2.2.0) 76 | jekyll (~> 3.1) 77 | octokit (~> 4.0, != 4.4.0) 78 | jekyll-mentions (1.2.0) 79 | activesupport (~> 4.0) 80 | html-pipeline (~> 2.3) 81 | jekyll (~> 3.0) 82 | jekyll-paginate (1.1.0) 83 | jekyll-redirect-from (0.11.0) 84 | jekyll (>= 2.0) 85 | jekyll-sass-converter (1.3.0) 86 | sass (~> 3.2) 87 | jekyll-seo-tag (2.0.0) 88 | jekyll (~> 3.1) 89 | jekyll-sitemap (0.11.0) 90 | addressable (~> 2.4.0) 91 | jekyll-swiss (0.4.0) 92 | jekyll-watch (1.5.0) 93 | listen (~> 3.0, < 3.1) 94 | jemoji (0.7.0) 95 | activesupport (~> 4.0) 96 | gemoji (~> 2.0) 97 | html-pipeline (~> 2.2) 98 | jekyll (>= 3.0) 99 | json (1.8.3) 100 | kramdown (1.11.1) 101 | liquid (3.0.6) 102 | listen (3.0.6) 103 | rb-fsevent (>= 0.9.3) 104 | rb-inotify (>= 0.9.7) 105 | mercenary (0.3.6) 106 | mini_portile2 (2.8.5) 107 | minima (2.0.0) 108 | minitest (5.9.1) 109 | multipart-post (2.0.0) 110 | net-dns (0.8.0) 111 | nokogiri (1.16.2) 112 | mini_portile2 (~> 2.8.2) 113 | racc (~> 1.4) 114 | octokit (4.6.0) 115 | sawyer (~> 0.8.0, >= 0.5.3) 116 | pathutil (0.14.0) 117 | forwardable-extended (~> 2.6) 118 | public_suffix (1.5.3) 119 | racc (1.7.3) 120 | rb-fsevent (0.9.8) 121 | rb-inotify (0.9.7) 122 | ffi (>= 0.5.0) 123 | rouge (1.11.1) 124 | safe_yaml (1.0.4) 125 | sass (3.4.22) 126 | sawyer (0.8.0) 127 | addressable (>= 2.3.5, < 2.6) 128 | faraday (~> 0.8, < 0.10) 129 | terminal-table (1.7.3) 130 | unicode-display_width (~> 1.1.1) 131 | thread_safe (0.3.6) 132 | typhoeus (0.8.0) 133 | ethon (>= 0.8.0) 134 | tzinfo (1.2.10) 135 | thread_safe (~> 0.1) 136 | unicode-display_width (1.1.1) 137 | 138 | PLATFORMS 139 | ruby 140 | 141 | DEPENDENCIES 142 | github-pages 143 | 144 | BUNDLED WITH 145 | 1.10.6 146 | -------------------------------------------------------------------------------- /test_projects/mojombo/README.md: -------------------------------------------------------------------------------- 1 | # This is the data for my blog 2 | 3 | It is automatically transformed by [Jekyll](http://github.com/mojombo/jekyll) 4 | into a static site whenever I push this repository to GitHub. 5 | 6 | I was tired of having my blog posts end up in a database off on some remote 7 | server. That is backwards. I've lost valuable posts that way. I want to author 8 | my posts locally in Textile or Markdown. My blog should be easily stylable and 9 | customizable any way I please. It should take care of creating a feed for me. 10 | And most of all, my site should be stored on GitHub so that I never lose data 11 | again. 12 | 13 | ## License 14 | 15 | The following directories and their contents are Copyright Tom Preston-Werner. 16 | You may not reuse anything therein without my permission: 17 | 18 | * \_posts/ 19 | * images/ 20 | 21 | All other directories and files are MIT Licensed. Feel free to use the HTML and 22 | CSS as you please. If you do use them, a link back to 23 | http://github.com/mojombo/jekyll would be appreciated, but is not required. 24 | -------------------------------------------------------------------------------- /test_projects/mojombo/_config.yaml: -------------------------------------------------------------------------------- 1 | time: 2022-02-01 14:01:48 2 | timezone: America/New_York 3 | -------------------------------------------------------------------------------- /test_projects/mojombo/_expected/2008/11/03/how-to-meet-your-next-cofounder.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | How to Meet Your Next Cofounder 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 |
29 |
30 | Tom Preston-Werner 31 | home 32 |
33 | 34 |
35 |

How to Meet Your Next Cofounder

36 | 37 |

3 Nov 2008 - San Francisco

38 | 39 |

Over the last few months I’ve seen a number of people looking for cofounders on 40 | Hacker News or via their own personal blogs. I think this is, at best, a highly 41 | inefficient way to find a cofounder and, at worst, a way to fool yourself into 42 | finding the wrong cofounder. In any case, it’s a naive approach to finding the 43 | person that will need to stand by your side in the coming storm that we call 44 | “running a startup.”

45 | 46 |

Don’t get me wrong, the internet is an amazing tool for meeting people. The 47 | wider the net you cast, the more likely you are to find the perfect match. But 48 | the internet has its limitations. I’ve had internet friends that were engaging, 49 | witty, and brilliant online, but in person felt awkward and boring. Conversely, 50 | I know people that are volatile and inflammatory online, but present an attitude 51 | of friendliness and caring in person. This phenomenon makes it difficult to 52 | gauge an individual’s personality from online interaction alone.

53 | 54 |

A far better use of the internet is to find groups of people that share your 55 | interests. Track down the local users group for your language or technology of 56 | choice. The simple fact that members of these groups take time out of their day 57 | to show up means that they’re more motivated and driven than the average person. 58 | Even if it’s a bit of a commute to get to the meetings, start showing up 59 | regularly. Prepare a few presentations on topics that you’re passionate about. 60 | Bonus points if you present on ideas related to your potential startup. Don’t 61 | worry about revealing your game-changing secrets; stealth mode is bullshit. Talk 62 | to everyone. Steer the conversation toward your interests and if someone there 63 | is excited about the same things, it will be clear.

64 | 65 |

It may take weeks or months, but in a good group you’ll find a handful of people 66 | that you really like. If at all possible, go out drinking with these people 67 | after the meetups. This is one of the easiest ways to go from “acquaintance” to 68 | “friend” and gives you free license to bring up your craziest of ideas without 69 | sounding like too much of a nutjob.

70 | 71 |

Of the people that you like, several may make excellent candidates for 72 | cofounders. Do a little research on these individuals. What does their code look 73 | like? Have they done much open source? Do they demonstrate an entrepreneurial 74 | spirit? Can they stick with a single project for a long time? Have they been 75 | loyal to their friends and companies in the past? A good cofounder should be 76 | someone with whom you feel privileged to work. And they should feel privileged 77 | to work with you. The two of you should be on very solid ground before you begin 78 | your startup adventure, because once you do, the impact of every argument is 79 | going to feel like it’s been multiplied by a thousand.

80 | 81 |

This all sounds like a lot of hard work. Maybe you’re wondering if it would be 82 | better to just go solo. I did that with Gravatar, and, in retrospect, it’s 83 | painfully obvious that I made a lot of stupid mistakes. When it’s just you and 84 | your thoughts it becomes too easy to pick the first thing that pops into your 85 | head. We’re programmed to think all of our ideas are good, but reality tells a 86 | different story. Truly good decisions are forged from the furnace of argument, 87 | not plucked like daisies from the pasture of a peaceful mind. A good cofounder 88 | tells you when your ideas are half-baked and ensures that your good ideas 89 | actually get implemented.

90 | 91 |

The second biggest danger with going solo is the loss of motivation. Solipsism 92 | might make you feel important at first, but the constant lack of feedback and 93 | the absence of support during tough times can easily lead to a premature end to 94 | your adventure. Cofounders are like workout buddies. Just when you think there’s 95 | no possible way you can do another rep, there they are, rooting you on toward an 96 | achievement that wouldn’t be possible without them.

97 | 98 |

Your choice of cofounder will affect everything you do in your startup. They’ll 99 | share every defeat with you and celebrate every success. They’ll help you 100 | understand your own ideas better by offering a different perspective. They’ll be 101 | the single most important decision you make during the tenure of your startup, 102 | so choose wisely and with extreme care.

103 | 104 |
105 | 106 | 118 | 119 | 143 |
144 | 145 | Fork me on GitHub 146 | 147 | 148 | 149 | 153 | 156 | 157 | 158 | 159 | 163 | 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /test_projects/mojombo/_expected/2010/08/23/readme-driven-development.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Readme Driven Development 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 |
29 |
30 | Tom Preston-Werner 31 | home 32 |
33 | 34 |
35 |

Readme Driven Development

36 | 37 |

23 August 2010 - San Francisco

38 | 39 |

I hear a lot of talk these days about TDD and BDD and Extreme Programming and SCRUM and stand up meetings and all kinds of methodologies and techniques for developing better software, but it’s all irrelevant unless the software we’re building meets the needs of those that are using it. Let me put that another way. A perfect implementation of the wrong specification is worthless. By the same principle a beautifully crafted library with no documentation is also damn near worthless. If your software solves the wrong problem or nobody can figure out how to use it, there’s something very bad going on.

40 | 41 |

Fine. So how do we solve this problem? It’s easier than you think, and it’s important enough to warrant its very own paragraph.

42 | 43 |

Write your Readme first.

44 | 45 |

First. As in, before you write any code or tests or behaviors or stories or ANYTHING. I know, I know, we’re programmers, dammit, not tech writers! But that’s where you’re wrong. Writing a Readme is absolutely essential to writing good software. Until you’ve written about your software, you have no idea what you’ll be coding. Between The Great Backlash Against Waterfall Design and The Supreme Acceptance of Agile Development, something was lost. Don’t get me wrong, waterfall design takes things way too far. Huge systems specified in minute detail end up being the WRONG systems specified in minute detail. We were right to strike it down. But what took its place is too far in the other direction. Now we have projects with short, badly written, or entirely missing documentation. Some projects don’t even have a Readme!

46 | 47 |

This is not acceptable. There must be some middle ground between reams of technical specifications and no specifications at all. And in fact there is. That middle ground is the humble Readme.

48 | 49 |

It’s important to distinguish Readme Driven Development from Documentation Driven Development. RDD could be considered a subset or limited version of DDD. By restricting your design documentation to a single file that is intended to be read as an introduction to your software, RDD keeps you safe from DDD-turned-waterfall syndrome by punishing you for lengthy or overprecise specification. At the same time, it rewards you for keeping libraries small and modularized. These simple reinforcements go a long way towards driving your project in the right direction without a lot of process to ensure you do the right thing.

50 | 51 |

By writing your Readme first you give yourself some pretty significant advantages:

52 | 53 |
    54 |
  • 55 |

    Most importantly, you’re giving yourself a chance to think through the project without the overhead of having to change code every time you change your mind about how something should be organized or what should be included in the Public API. Remember that feeling when you first started writing automated code tests and realized that you caught all kinds of errors that would have otherwise snuck into your codebase? That’s the exact same feeling you’ll have if you write the Readme for your project before you write the actual code.

    56 |
  • 57 |
  • 58 |

    As a byproduct of writing a Readme in order to know what you need to implement, you’ll have a very nice piece of documentation sitting in front of you. You’ll also find that it’s much easier to write this document at the beginning of the project when your excitement and motivation are at their highest. Retroactively writing a Readme is an absolute drag, and you’re sure to miss all kinds of important details when you do so.

    59 |
  • 60 |
  • 61 |

    If you’re working with a team of developers you get even more mileage out of your Readme. If everyone else on the team has access to this information before you’ve completed the project, then they can confidently start work on other projects that will interface with your code. Without any sort of defined interface, you have to code in serial or face reimplementing large portions of code.

    62 |
  • 63 |
  • 64 |

    It’s a lot simpler to have a discussion based on something written down. It’s easy to talk endlessly and in circles about a problem if nothing is ever put to text. The simple act of writing down a proposed solution means everyone has a concrete idea that can be argued about and iterated upon.

    65 |
  • 66 |
67 | 68 |

Consider the process of writing the Readme for your project as the true act of creation. This is where all your brilliant ideas should be expressed. This document should stand on its own as a testament to your creativity and expressiveness. The Readme should be the single most important document in your codebase; writing it first is the proper thing to do.

69 | 70 |

71 | 72 |

Discuss this post on Hacker News

73 | 74 |
75 | 76 | 88 | 89 | 113 |
114 | 115 | Fork me on GitHub 116 | 117 | 118 | 119 | 123 | 126 | 127 | 128 | 129 | 133 | 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /test_projects/mojombo/_expected/2010/12/11/designer-architect-developer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Designer, Architect, Developer 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 |
29 |
30 | Tom Preston-Werner 31 | home 32 |
33 | 34 |
35 |

Designer, Architect, Developer

36 | 37 |

11 Dec 2010 - San Francisco

38 | 39 |

Over the last six years I’ve bootstrapped three successful enterprises (Cube6 Media, Gravatar, and GitHub) and failed to gain traction with a handful of others. After a lot of thought and reflections on these experiences, I’ve identified three major skills that should be present in order to best build a successful web application. These roles can be loosely defined as the Designer, the Architect, and the Developer.

40 | 41 |

In college I spent a lot of time in the campus dark room dipping rolls of film and sheets of paper into various chemical baths beneath a dim red light. The most interesting part, though, was mounting the negative into the projector and exposing the photo paper. Every time I turned on the bright light of the projector I was reminded of a saying that has stuck with me ever since: “A photograph is nothing more than an image created by light.” Think about that for a second. The only way the photograph, and hence, the viewer, interact with the original subject is via the light that was captured. None of the fancy flashes, soft boxes, bounces, umbrellas, or backdrops mean a thing if the light they produce or redirect is in the wrong place. If the light is bad, the photograph is bad.

42 | 43 |

I think the same concept holds true for web applications. Adapting the saying for our own situation, I would say: “A web application is nothing more than an experience created by design.” Users can’t see what technology you use or whether you follow an agile development process or not. All they experience is what’s on the screen. It can’t be confusing, it can’t look amateur, and it can’t have spelling errors. If the UX is bad, the web application is bad. It’s that simple.

44 | 45 |

The way you get good UX is by having a good designer. Someone on the team must be skilled not only in making things pretty, but in making them usable as well. Without a good UX/visual design, you may as well not even bother. It’s impossible to stress how important this is.

46 | 47 |

Design comes first. It defines what you will build. Once you have an idea of what you’re creating, you need to figure out how to make it happen. That’s where the Architect comes in.

48 | 49 |

With the recent explosion of open source solutions to common problems like databases, web frameworks, job processors, messaging systems, etc, you need a team member that has a broad understanding of the technology landscape. The choices you make early on will impact your company for many years, and the wrong choices can spell disaster. The role of the Architect is to choose the best tools for the job, and to decide when new tools need to be created.

50 | 51 |

The Architect must also be ready to scale any piece of the site when you start attracting users. There’s a fine line between premature optimization and crumbling under the wave of thousands of new signups. A good architect will always be one step ahead of the curve, laying the groundwork for future scaling needs just before they are needed.

52 | 53 |

Design and architecture dictate what you build and how you build it, but without someone to do the construction, you’re dead in the water. The role of the Developer is to turn the wishes of the Designer into reality while staying within the constraints that the Architect has put forth. In addition, the Developer has to ensure that the codebase remains healthy and protect against technical debt. Sloppy development up front means a huge amount of wasted effort later on.

54 | 55 |

The three roles of the Designer, the Architect, and the Developer may reside in a single person, but it’s much more common to see groups of two or three people satisfy all these skills. In fact, the best founding teams are those where everyone fills some combination of roles. This fosters an environment of friendly argument that leads to better decisions.

56 | 57 |

But whatever you do, make sure your team fills all of these roles. Once you do, executing on your idea should come easily!

58 | 59 |
60 | 61 | 73 | 74 | 98 |
99 | 100 | Fork me on GitHub 101 | 102 | 103 | 104 | 108 | 111 | 112 | 113 | 114 | 118 | 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /test_projects/mojombo/_expected/2014/04/21/farewell-github-hello-immersive-computing.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Farewell GitHub, Hello Immersive Computing 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 |
29 |
30 | Tom Preston-Werner 31 | home 32 |
33 | 34 |
35 |

Farewell GitHub, Hello Immersive Computing

36 | 37 |

21 Apr 2014 - New York City

38 | 39 |

Today is my last day at GitHub. Recent events have given me a lot of time to 40 | reflect on what’s important to me, and I’ve decided to switch gears and focus on 41 | building something from scratch again. Since visiting the Oculus VR team at 42 | their office three months ago, I’ve come to believe that immersive computing 43 | (aka virtual reality) is poised to rival the personal computer, the web, social 44 | networking, and mobile devices in its impact. While the timing is more abrupt 45 | than I had intended, with everything that’s happened, I think now is the right 46 | time to do this, and I’d like to explain why.

47 | 48 |

First, I want to address the serious accusations that were made against me and 49 | my family over the past month. With every decision I made at GitHub and in every 50 | interaction I had with employees, I tried to treat people better than they 51 | expected and to resolve conflict with empathy. Despite that, I’ve made mistakes, 52 | and I am deeply sorry to anyone who was hurt by those mistakes. It devastates me 53 | to know that I missed the mark, and I will strive to do better, every day.

54 | 55 |

That said, I want to be very clear about one thing: neither my wife, Theresa, 56 | nor I have ever engaged in gender-based harassment or discrimination. The 57 | results of GitHub’s independent investigation unequivocally confirm this and we 58 | are prepared to fight any further false claims on this matter to the full extent 59 | of the law. I believe in diversity and equality for all people in all 60 | professions, especially the tech sector. It’s immensely important to me and I 61 | will continue to do my very best to further that belief.

62 | 63 |

Unfortunately, the investigation and all the attention surrounding it have me 64 | concerned that remaining at GitHub would be a distraction for both me and the 65 | company. I’m incredibly proud of what I’ve helped build at GitHub and I don’t 66 | want the events of the past month to jeopardize that. I care too much about the 67 | company and the people here to let that happen. The GitHub team is incredibly 68 | strong, with fierce vision, and I have no doubt they will continue to 69 | revolutionize software development for decades to come. Founding and building 70 | GitHub has been the greatest adventure of my life. I’ve been so lucky to be on 71 | this journey with such amazing, helpful, talented, and real people. I’m going to 72 | miss working with such a great team, but I’m also insanely excited about the 73 | future.

74 | 75 |

Since the early days of GitHub, I’ve wanted to create a different kind of 76 | business. One that was Optimized for 77 | Happiness 78 | and built atop a Framework of 79 | Happiness. One where great people 80 | could work on hard problems together to create unbelievably good products. I 81 | believe I was able to achieve a great deal of success with that model at GitHub, 82 | even if things didn’t always go perfectly according to plan. All of this has 83 | been a tremendous learning experience for me.

84 | 85 |

Last January I stepped down as CEO and handed that role over to cofounder Chris 86 | Wanstrath so I could focus on future-facing R&D projects with small teams. This 87 | kind of rapid, team-based innovation is what I live for. During my time away 88 | from GitHub I started experimenting with Go, OpenGL, and Unity with an eye 89 | towards the software side of immersive computing. It felt really good to get 90 | back into a code editor and challenge the deeply logical and analytical part of 91 | my brain. I’ve enjoyed the challenges of learning how to lead a company with 92 | hundreds of people, but it’s very hard for me to deny the allure of coding a 93 | system that could once again change the course of history.

94 | 95 |

I’m telling you this because I think stealth mode is bullshit and if you feel 96 | the same way I do about immersive computing then I want to talk with you about 97 | it. For the next few months I’m going to be living in Manhattan. My wife, 98 | Theresa, is currently participating in Techstars NYC as their very first 99 | nonprofit. Her startup, The Omakase Charity, 100 | helps donors learn about and support nonprofits that are changing the world with 101 | technology. She’s one of the strongest and most thoughtful women I know, and I’m 102 | hoping to help her succeed with her mission while I’m here.

103 | 104 |

Thank you to everyone that reached out to me over the last month, including the 105 | generous team at Andreessen Horowitz. Your support has made a huge difference 106 | and I’m truly excited for what’s next.

107 | 108 |
109 | 110 | 122 | 123 | 147 |
148 | 149 | Fork me on GitHub 150 | 151 | 152 | 153 | 157 | 160 | 161 | 162 | 163 | 167 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /test_projects/mojombo/_expected/2015/06/19/replicated.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Replicated - An Easier Path from SaaS to Enterprise 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 |
29 |
30 | Tom Preston-Werner 31 | home 32 |
33 | 34 |
35 |

Replicated - An Easier Path from SaaS to Enterprise

36 | 37 |

19 Jun 2015 - San Francisco

38 | 39 |

Over the last year I’ve had a chance to learn a lot more about early stage 40 | funding and made angel investments in a handful of startups. So far I’ve 41 | restricted my involvement to companies with ideas in which I have significant 42 | domain knowledge. I also insist on founders with relentless product focus, a 43 | fierce desire to help their customers be more awesome, and excellent 44 | communication skills. I recently met just such a company, with just such 45 | founders, tackling a problem that has personally caused me much pain.

46 | 47 |

The company is Replicated, and founders Grant Miller 48 | and Marc Campbell are making it easier to roll out an on-prem Enterprise 49 | offering based on an existing cloud-based SaaS product.

50 | 51 |

At GitHub, we burned through a lot of developer cycles building our own 52 | installer (several times), securing the installation environment, coding an 53 | automated licensing management system, integrating single sign-on services 54 | (LDAP, Active Directory, CAS, etc, etc), building out a searchable audit system, 55 | supporting customer-reviewable support bundles (logs and other diagnostic 56 | output), allowing numerous backup strategies, and countless other 57 | Enterprise-specific features that were killing our Enterprise deals. All of this 58 | on top of hiring and building out the necessary sales, support, and accounting 59 | teams to create a smooth Enterprise experience for our customers.

60 | 61 |

Replicated provides common Enterprise functionality (much of what I mentioned 62 | above, and all of it eventually) that you can wrap around your SaaS product, 63 | resulting in a first-class on-prem product in a fraction of the time. Beyond 64 | just technology, Replicated will help you understand your Enterprise customers 65 | through documentation on best practices and insight into the requirements and 66 | reasons that large companies desire the features they do. Until you can 67 | empathise with your customer (which is very hard to do as a fast-moving SaaS 68 | startup), you’ll never build the best product possible.

69 | 70 |

Getting into the Enterprise market will always be hard. But by reducing the 71 | technology burden, Replicated plans to erase much of the pain so you can focus 72 | on the other human-centric tasks. Not only am I an investor in Replicated, I 73 | believe in their mission and their founders so much that I’ve joined as an 74 | advisor. I understand what the uphill slog of the SaaS to Enterprise climb feels 75 | like, and I’m going to do my best to ensure you don’t have to suffer it as much 76 | as I did.

77 | 78 |

I’m also pleased to announce that Travis CI is now shipping their Enterprise 79 | product using Replicated. To see what the installation process is like, watch 80 | Grant install Travis CI 81 | Enterprise on a 82 | fresh server in about seven minutes. For a deeper dive, Travis CI has also 83 | published a blog post covering some of their process in getting their 84 | Enterprise installer ready using 85 | Replicated.

86 | 87 |

In the coming weeks, you’ll start to see other well-known startups launching (or 88 | re-launching) Enterprise versions of their SaaS software on top of Replicated. 89 | If you’re looking to do the same, and want to save yourself a lot of heartache, 90 | email contact@replicated.com, and start 91 | focusing on what matters the most: your unique and kickass product.

92 | 93 |
94 | 95 | 107 | 108 | 132 |
133 | 134 | Fork me on GitHub 135 | 136 | 137 | 138 | 142 | 145 | 146 | 147 | 148 | 152 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /test_projects/mojombo/_expected/README.md: -------------------------------------------------------------------------------- 1 | # This is the data for my blog 2 | 3 | It is automatically transformed by [Jekyll](http://github.com/mojombo/jekyll) 4 | into a static site whenever I push this repository to GitHub. 5 | 6 | I was tired of having my blog posts end up in a database off on some remote 7 | server. That is backwards. I've lost valuable posts that way. I want to author 8 | my posts locally in Textile or Markdown. My blog should be easily stylable and 9 | customizable any way I please. It should take care of creating a feed for me. 10 | And most of all, my site should be stored on GitHub so that I never lose data 11 | again. 12 | 13 | ## License 14 | 15 | The following directories and their contents are Copyright Tom Preston-Werner. 16 | You may not reuse anything therein without my permission: 17 | 18 | * \_posts/ 19 | * images/ 20 | 21 | All other directories and files are MIT Licensed. Feel free to use the HTML and 22 | CSS as you please. If you do use them, a link back to 23 | http://github.com/mojombo/jekyll would be appreciated, but is not required. 24 | -------------------------------------------------------------------------------- /test_projects/mojombo/_expected/css/screen.css: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* 3 | /* Common 4 | /* 5 | /*****************************************************************************/ 6 | 7 | /* Global Reset */ 8 | 9 | * { 10 | margin: 0; 11 | padding: 0; 12 | } 13 | 14 | html, body { 15 | height: 100%; 16 | } 17 | 18 | body { 19 | background-color: white; 20 | font: 13.34px helvetica, arial, clean, sans-serif; 21 | *font-size: small; 22 | text-align: center; 23 | } 24 | 25 | h1, h2, h3, h4, h5, h6 { 26 | font-size: 100%; 27 | } 28 | 29 | h1 { 30 | margin-bottom: 1em; 31 | } 32 | 33 | p { 34 | margin: 1em 0; 35 | } 36 | 37 | a { 38 | color: #00a; 39 | } 40 | 41 | a:hover { 42 | color: black; 43 | } 44 | 45 | a:visited { 46 | color: #a0a; 47 | } 48 | 49 | table { 50 | font-size: inherit; 51 | font: 100%; 52 | } 53 | 54 | /*****************************************************************************/ 55 | /* 56 | /* Home 57 | /* 58 | /*****************************************************************************/ 59 | 60 | ul.posts { 61 | list-style-type: none; 62 | margin-bottom: 2em; 63 | } 64 | 65 | ul.posts li { 66 | line-height: 1.75em; 67 | } 68 | 69 | ul.posts span { 70 | color: #aaa; 71 | font-family: Monaco, "Courier New", monospace; 72 | font-size: 80%; 73 | } 74 | 75 | /*****************************************************************************/ 76 | /* 77 | /* Site 78 | /* 79 | /*****************************************************************************/ 80 | 81 | .site { 82 | font-size: 110%; 83 | text-align: justify; 84 | width: 42em; 85 | margin: 3em auto 2em auto; 86 | line-height: 1.5em; 87 | } 88 | 89 | .title { 90 | color: #a00; 91 | font-weight: bold; 92 | margin-bottom: 2em; 93 | } 94 | 95 | .site .title a { 96 | color: #a00; 97 | text-decoration: none; 98 | } 99 | 100 | .site .title a:hover { 101 | color: black; 102 | } 103 | 104 | .site .title a.extra { 105 | color: #aaa; 106 | text-decoration: none; 107 | margin-left: 1em; 108 | } 109 | 110 | .site .title a.extra:hover { 111 | color: black; 112 | } 113 | 114 | .site .meta { 115 | color: #aaa; 116 | } 117 | 118 | .site .footer { 119 | font-size: 80%; 120 | color: #666; 121 | border-top: 4px solid #eee; 122 | margin-top: 2em; 123 | overflow: hidden; 124 | } 125 | 126 | .site .footer .contact { 127 | float: left; 128 | margin-right: 3em; 129 | } 130 | 131 | .site .footer .contact a { 132 | color: #8085C1; 133 | } 134 | 135 | .site .footer .rss { 136 | margin-top: 1.1em; 137 | margin-right: -.2em; 138 | float: right; 139 | } 140 | 141 | .site .footer .rss img { 142 | border: 0; 143 | } 144 | 145 | /*****************************************************************************/ 146 | /* 147 | /* Posts 148 | /* 149 | /*****************************************************************************/ 150 | 151 | #post { 152 | 153 | } 154 | 155 | /* standard */ 156 | 157 | #post pre { 158 | border: 1px solid #ddd; 159 | background-color: #eef; 160 | padding: 0 .4em; 161 | } 162 | 163 | #post ul, 164 | #post ol { 165 | margin-left: 1.35em; 166 | } 167 | 168 | #post code { 169 | border: 1px solid #ddd; 170 | background-color: #eef; 171 | font-size: 85%; 172 | padding: 0 .2em; 173 | } 174 | 175 | #post pre code { 176 | border: none; 177 | } 178 | 179 | #post img { 180 | max-width: 42em; 181 | padding: 1em 0; 182 | } 183 | 184 | /* terminal */ 185 | 186 | #post pre.terminal { 187 | border: 1px solid black; 188 | background-color: #333; 189 | color: white; 190 | } 191 | 192 | #post pre.terminal code { 193 | background-color: #333; 194 | } 195 | 196 | #related { 197 | margin-top: 2em; 198 | } 199 | 200 | #related h2 { 201 | margin-bottom: 1em; 202 | } 203 | -------------------------------------------------------------------------------- /test_projects/mojombo/_expected/css/syntax.css: -------------------------------------------------------------------------------- 1 | .highlight { background: #ffffff; } 2 | .highlight .c { color: #999988; font-style: italic } /* Comment */ 3 | .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ 4 | .highlight .k { font-weight: bold } /* Keyword */ 5 | .highlight .o { font-weight: bold } /* Operator */ 6 | .highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ 7 | .highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ 8 | .highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ 9 | .highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ 10 | .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ 11 | .highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ 12 | .highlight .ge { font-style: italic } /* Generic.Emph */ 13 | .highlight .gr { color: #aa0000 } /* Generic.Error */ 14 | .highlight .gh { color: #999999 } /* Generic.Heading */ 15 | .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ 16 | .highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ 17 | .highlight .go { color: #888888 } /* Generic.Output */ 18 | .highlight .gp { color: #555555 } /* Generic.Prompt */ 19 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 20 | .highlight .gu { color: #aaaaaa } /* Generic.Subheading */ 21 | .highlight .gt { color: #aa0000 } /* Generic.Traceback */ 22 | .highlight .kc { font-weight: bold } /* Keyword.Constant */ 23 | .highlight .kd { font-weight: bold } /* Keyword.Declaration */ 24 | .highlight .kp { font-weight: bold } /* Keyword.Pseudo */ 25 | .highlight .kr { font-weight: bold } /* Keyword.Reserved */ 26 | .highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ 27 | .highlight .m { color: #009999 } /* Literal.Number */ 28 | .highlight .s { color: #d14 } /* Literal.String */ 29 | .highlight .na { color: #008080 } /* Name.Attribute */ 30 | .highlight .nb { color: #0086B3 } /* Name.Builtin */ 31 | .highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ 32 | .highlight .no { color: #008080 } /* Name.Constant */ 33 | .highlight .ni { color: #800080 } /* Name.Entity */ 34 | .highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ 35 | .highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ 36 | .highlight .nn { color: #555555 } /* Name.Namespace */ 37 | .highlight .nt { color: #000080 } /* Name.Tag */ 38 | .highlight .nv { color: #008080 } /* Name.Variable */ 39 | .highlight .ow { font-weight: bold } /* Operator.Word */ 40 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 41 | .highlight .mf { color: #009999 } /* Literal.Number.Float */ 42 | .highlight .mh { color: #009999 } /* Literal.Number.Hex */ 43 | .highlight .mi { color: #009999 } /* Literal.Number.Integer */ 44 | .highlight .mo { color: #009999 } /* Literal.Number.Oct */ 45 | .highlight .sb { color: #d14 } /* Literal.String.Backtick */ 46 | .highlight .sc { color: #d14 } /* Literal.String.Char */ 47 | .highlight .sd { color: #d14 } /* Literal.String.Doc */ 48 | .highlight .s2 { color: #d14 } /* Literal.String.Double */ 49 | .highlight .se { color: #d14 } /* Literal.String.Escape */ 50 | .highlight .sh { color: #d14 } /* Literal.String.Heredoc */ 51 | .highlight .si { color: #d14 } /* Literal.String.Interpol */ 52 | .highlight .sx { color: #d14 } /* Literal.String.Other */ 53 | .highlight .sr { color: #009926 } /* Literal.String.Regex */ 54 | .highlight .s1 { color: #d14 } /* Literal.String.Single */ 55 | .highlight .ss { color: #990073 } /* Literal.String.Symbol */ 56 | .highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ 57 | .highlight .vc { color: #008080 } /* Name.Variable.Class */ 58 | .highlight .vg { color: #008080 } /* Name.Variable.Global */ 59 | .highlight .vi { color: #008080 } /* Name.Variable.Instance */ 60 | .highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ 61 | -------------------------------------------------------------------------------- /test_projects/mojombo/_expected/images/posts/2016-11-10/breaches.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/mojombo/_expected/images/posts/2016-11-10/breaches.png -------------------------------------------------------------------------------- /test_projects/mojombo/_expected/images/rss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/mojombo/_expected/images/rss.png -------------------------------------------------------------------------------- /test_projects/mojombo/_expected/pgp.txt: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | Version: GnuPG v1.4.11 (Darwin) 3 | 4 | mQENBE9e0pIBCADXib13PNjCbKH0dbCGMRDNDtg1Fp75t/jr7lqJE8C9B5XlrAXb 5 | O1uScvzRUt+myNyEhk21lA8KmTR0f1up84frxdTV7H4evePWbYbKigVu5zKKAvnG 6 | hGPnxtAslxvB/0fV1s+1IFpIG2VADHTaJ3ESyXR21S3tx9Uca3WQ9H2Jq32ur0Ox 7 | eCvRD1Tu8/YXLtOi3oyZZssqy7L9NpYOCZG7mQunds7LGSfz8ucWLlgUunV3seHB 8 | R0CUSYccphRAfrtr4lPbb9RXrXNVKtcoHbiDnSnzayjcghvjQuPDyca09fJDO4nk 9 | NlUlJmc0Pgcc4eFcCAnuVIR8RamGZ/+0gZDBABEBAAG0Q1RvbSBQcmVzdG9uLVdl 10 | cm5lciAoQ29mb3VuZGVyICYgQ1RPLCBHaXRIdWIsIEluYy4pIDx0b21AZ2l0aHVi 11 | LmNvbT6JATgEEwECACIFAk9e0pICGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheA 12 | AAoJEKphtGN5qvflqU4H/jAxh8YMwbSWgnilFbhYPoYL+jPyY74pA/fNSYcTy7qH 13 | 5vVNfImuQ94oyQZosq85J1jXT1ln/liQzdbdKTt36HQDGTSyRJD2FfVUmFMYtC8B 14 | IR+RpaCqNdboZPxZcmuFSERqjv1xEyc+9tAlsMg+T8CwpDUft2OgS46SyMcVZ0dh 15 | G56zrZAR/x/ZapxrIfAzRj6CSunJEa82BCvgkzI8X8BsMdiEFT5A02wrFCA7qbDv 16 | +197SiV0Ishv2m5WeU/qGIUsps3TLgeyZnyiqYKQZcIFBhZ0PR+WQRbw2Ct7Yefz 17 | b8wcT6if8mZGZrGOBJorCZe50AUKHkaS+JoPXzGexIC5AQ0ET17SkgEIALvtGjPp 18 | Vx87cC1nkcd3iRpv+/02wb5u/KiQqa0qmW3u3wcKTVlk58ZLhNxDqH/l+ClzhKpb 19 | nb6c3hCkLF9te1royibkJGlb83YAJLDJM3a389Sd1vfgFNk7POdSgZ72EPzGiUnn 20 | o8cZRXPhThbuL0D6ZA3oUfW23VVt+3oh3ieF9cnhaPL/d+te9lfvypt6BERdzoYp 21 | JF4bWl0MN0GALW5lH0AkoEYBM7kLyWqEqB1wie4xEsh9cRbx5e5KCJFD6JyT9g80 22 | HUDJyJV9D6SEIU2lyqBnVSuRE16jmAEZuUqhldpZocNtmrF0JF5evciYPnJrULD2 23 | YTepopzPXCGAqdUAEQEAAYkBHwQYAQIACQUCT17SkgIbDAAKCRCqYbRjear35SKk 24 | CACpmJXhORU12Sjmyfpgs4z+t1kGbuaRvJl18llZ3T2mzxs1mDV1uTZ7eVc+af+e 25 | HkhEaIVO35By6sg4Y2xV8cW+J+YKUpGTKoUVqb0tLn2R/xJx1hbQUle3rOlfOCO3 26 | dHclvXzYAsRGwMpOj8idu8Q8yUH2FncRU7iCxmkgxtp6/tPo06z9ZYsAM1DyELcj 27 | Y2jJ57A8urwkbRCBXGJnAYCM70MPXPKuxheL3mDPHHgE5aUWc4BQH9Oz4PWeuVGB 28 | ZGjzDtHLzltuWZQXURNk3nklDG84AZ8SLMxMlNvYqfwVqhLld7rQkncjH8/kkUxJ 29 | jrpwB041z2lIc22q/ZDsctSM 30 | =vrTm 31 | -----END PGP PUBLIC KEY BLOCK----- 32 | -------------------------------------------------------------------------------- /test_projects/mojombo/_expected/random/canvas_rotated_textfill.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Canvas Rotated textFill 5 | 6 | 7 | 8 | 9 | 53 | 54 | -------------------------------------------------------------------------------- /test_projects/mojombo/_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ page.title }} 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 |
29 |
30 | Tom Preston-Werner 31 | home 32 |
33 | 34 | {{ content }} 35 | 36 | 60 |
61 | 62 | Fork me on GitHub 63 | 64 | 65 | 66 | 70 | 73 | 74 | 75 | 76 | 80 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /test_projects/mojombo/_layouts/post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 |
5 | {{ content }} 6 |
7 | 8 | -------------------------------------------------------------------------------- /test_projects/mojombo/_posts/2008-10-18-how-i-turned-down-300k.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: How I Turned Down $300,000 from Microsoft to go Full-Time on GitHub 4 | --- 5 | 6 | {{ page.title }} 7 | ================ 8 | 9 |

18 Oct 2008 - San Francisco

10 | 11 | 2008 is a leap year. That means that three hundred and sixty six days ago, 12 | almost to the minute, I was sitting alone in a booth at Zeke's Sports Bar and 13 | Grill on 3rd Street in San Francisco. I wouldn't normally hang out at a sports 14 | bar, let alone a sports bar in SOMA, but back then Thursday was "I Can Has Ruby" 15 | night. I guess back then "I can has _______" was also a reasonable moniker to 16 | attach to pretty much anything. ICHR was a semi-private meeting of like minded 17 | Ruby Hackers that generally and willingly devolved into late night drinking 18 | sessions. Normally these nights would fade away like my hangover the next 19 | morning, but this night was different. This was the night that 20 | [GitHub](http://github.com/) was born. 21 | 22 | I think I was sitting at the booth alone because I'd just ordered a fresh Fat 23 | Tire and needed a short break from the socializing that was happening over at 24 | the long tables in the dimly lit aft portion of the bar. On the fifth or sixth 25 | sip, Chris Wanstrath walked in. I have trouble remembering now if I'd even 26 | classify Chris and I as "friends" at the time. We knew each other through Ruby 27 | meetups and conferences, but only casually. Like a mutual "hey, I think your 28 | code is awesome" kind of thing. I'm not sure what made me do it, but I gestured 29 | him over to the booth and said "dude, check this out." About a week earlier I'd 30 | started work on a project called [Grit](http://github.com/mojombo/grit) that 31 | allowed me to access Git repositories in an object oriented manner via Ruby 32 | code. Chris was one of only a handful of Rubyists at the time that was starting 33 | to become serious about Git. He sat down and I started showing him what I had. 34 | It wasn't much, but it was enough to see that it had sparked something in Chris. 35 | Sensing this, I launched into my half-baked idea for some sort of website that 36 | acted as hub for coders to share their Git repositories. I even had a name: 37 | GitHub. I may be paraphrasing, but his response was along the lines of a very 38 | emphatic "I'm in. Let's do it!" 39 | 40 | The next night, Friday, October 19, 2007 at 10:24pm Chris made the first commit 41 | to the GitHub repository and sealed in digital stone the beginning of our joint 42 | venture. There were, so far, no agreements of any kind regarding how things 43 | would proceed. Just two guys that decided to hack together on something that 44 | sounded cool. 45 | 46 | Remember those amazing few minutes in Karate Kid where Daniel is training to 47 | become a martial arts expert? Remember the music? Well, you should probably go 48 | buy and listen to [You're The 49 | Best](http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?i=260417864&id=260417040&s=143441) 50 | by Joe Esposito in iTunes because I'm about to hit you with a montage. 51 | 52 | For the next three months Chris and I spent ridiculous hours planning and coding 53 | GitHub. I kept going with Grit and designed the UI. Chris built out the Rails 54 | app. We met in person every Saturday to make design decisions and try to figure 55 | out what the hell our pricing plan would look like. I remember one very rainy 56 | day we talked for a good two hours about various pricing strategies over some of 57 | the best Vietnamese egg rolls in the city. All of this we did while holding 58 | other engagements. I, for one, was employed full time at Powerset as a tools 59 | developer for the Ranking and Relevance team. 60 | 61 | In mid January, after three months of nights and weekends, we launched into 62 | private beta mode, sending invites to our friends. In mid February PJ Hyett 63 | joined in and made us three-strong. We publicly launched the site on April 10th. 64 | TechCrunch was not invited. At this point it was still just three 20-somethings 65 | without a single penny of outside investment. 66 | 67 | I was still working full time at Powerset on July 1, 2008 when we learned that 68 | Powerset had just been acquired by Microsoft for around $100 million. This was 69 | interesting timing. With the acquisition, I was going to be faced with a choice 70 | sooner than I had anticipated. I could either sign on as a Microsoft employee or 71 | quit and go GitHub full time. At 29 years old, I was the oldest of the three 72 | GitHubbers, and had accumulated a proportionally larger amount of debt and 73 | monthly expenditure. I was used to my six digit lifestyle. Further confounding 74 | the issue was the imminent return of my wife, Theresa, from her PhD fieldwork in 75 | Costa Rica. I would soon be transitioning from make-believe bachelor back to 76 | married man. 77 | 78 | To muddy the waters of decision even more, the Microsoft employment offer was 79 | juicy. Salary + $300k over three years juicy. That's enough money to make 80 | anybody think twice about anything. So I was faced with this: a safe job with 81 | lots of guaranteed money as a Microsoft man –or– a risky job with 82 | unknown amounts of money as an entrepreneur. I knew things with the other GitHub 83 | guys would become extremely strained if I stayed on at Powerset much longer. 84 | Having saved up some money and become freelancers some time ago, they had both 85 | started dedicating full time effort to GitHub. It was do or die time. Either 86 | pick GitHub and go for it, or make the safe choice and quit GitHub to make 87 | wheelbarrows full of cash at Microsoft. 88 | 89 | If you want a recipe for restless sleep, I can give you one. Add one part "what 90 | will my wife think" with 3,000 parts Benjamin Franklin; stir in a "beer anytime 91 | you damn well please" and top with a chance at financial independence. 92 | 93 | I've become pretty good at giving my employers the bad news that I'm leaving the 94 | company to go do something cooler. I broke the news to my boss at Powerset on 95 | the day the employment offer was due. I told him I was quitting to go work full 96 | time on GitHub. Like any great boss, he was bummed, but understanding. He didn't 97 | try to tempt me with a bigger bonus or anything. I think deep down he knew I was 98 | going to leave. I may have even received a larger incentive to stay than others, 99 | on account of my being a flight risk. Those Microsoft managers are crafty, I 100 | tell you. They've got retention bonuses down to a science. Well, except when you 101 | throw an entrepreneur, the singularity of the business world, into the mix. 102 | Everything goes wacky when you've got one of those around. 103 | 104 | In the end, just as Indiana Jones could never turn down the opportunity to 105 | search for the Holy Grail, I could no less turn down the chance to work for 106 | myself on something I truly love, no matter how safe the alternative might be. 107 | When I'm old and dying, I plan to look back on my life and say "wow, that was an 108 | adventure," not "wow, I sure felt safe." 109 | -------------------------------------------------------------------------------- /test_projects/mojombo/_posts/2008-11-03-how-to-meet-your-next-cofounder.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: How to Meet Your Next Cofounder 4 | --- 5 | 6 | {{ page.title }} 7 | ================ 8 | 9 |

3 Nov 2008 - San Francisco

10 | 11 | Over the last few months I've seen a number of people looking for cofounders on 12 | Hacker News or via their own personal blogs. I think this is, at best, a highly 13 | inefficient way to find a cofounder and, at worst, a way to fool yourself into 14 | finding the *wrong* cofounder. In any case, it's a naive approach to finding the 15 | person that will need to stand by your side in the coming storm that we call 16 | "running a startup." 17 | 18 | Don't get me wrong, the internet is an amazing tool for meeting people. The 19 | wider the net you cast, the more likely you are to find the perfect match. But 20 | the internet has its limitations. I've had internet friends that were engaging, 21 | witty, and brilliant online, but in person felt awkward and boring. Conversely, 22 | I know people that are volatile and inflammatory online, but present an attitude 23 | of friendliness and caring in person. This phenomenon makes it difficult to 24 | gauge an individual's personality from online interaction alone. 25 | 26 | A far better use of the internet is to find groups of people that share your 27 | interests. Track down the local users group for your language or technology of 28 | choice. The simple fact that members of these groups take time out of their day 29 | to show up means that they're more motivated and driven than the average person. 30 | Even if it's a bit of a commute to get to the meetings, start showing up 31 | regularly. Prepare a few presentations on topics that you're passionate about. 32 | Bonus points if you present on ideas related to your potential startup. Don't 33 | worry about revealing your game-changing secrets; stealth mode is bullshit. Talk 34 | to everyone. Steer the conversation toward your interests and if someone there 35 | is excited about the same things, it will be clear. 36 | 37 | It may take weeks or months, but in a good group you'll find a handful of people 38 | that you really like. If at all possible, go out drinking with these people 39 | after the meetups. This is one of the easiest ways to go from "acquaintance" to 40 | "friend" and gives you free license to bring up your craziest of ideas without 41 | sounding like too much of a nutjob. 42 | 43 | Of the people that you like, several may make excellent candidates for 44 | cofounders. Do a little research on these individuals. What does their code look 45 | like? Have they done much open source? Do they demonstrate an entrepreneurial 46 | spirit? Can they stick with a single project for a long time? Have they been 47 | loyal to their friends and companies in the past? A good cofounder should be 48 | someone with whom you feel privileged to work. And they should feel privileged 49 | to work with you. The two of you should be on very solid ground before you begin 50 | your startup adventure, because once you do, the impact of every argument is 51 | going to feel like it's been multiplied by a thousand. 52 | 53 | This all sounds like a lot of hard work. Maybe you're wondering if it would be 54 | better to just go solo. I did that with Gravatar, and, in retrospect, it's 55 | painfully obvious that I made a lot of stupid mistakes. When it's just you and 56 | your thoughts it becomes too easy to pick the first thing that pops into your 57 | head. We're programmed to think all of our ideas are good, but reality tells a 58 | different story. Truly good decisions are forged from the furnace of argument, 59 | not plucked like daisies from the pasture of a peaceful mind. A good cofounder 60 | tells you when your ideas are half-baked and ensures that your good ideas 61 | actually get implemented. 62 | 63 | The second biggest danger with going solo is the loss of motivation. Solipsism 64 | might make you feel important at first, but the constant lack of feedback and 65 | the absence of support during tough times can easily lead to a premature end to 66 | your adventure. Cofounders are like workout buddies. Just when you think there's 67 | no possible way you can do another rep, there they are, rooting you on toward an 68 | achievement that wouldn't be possible without them. 69 | 70 | Your choice of cofounder will affect everything you do in your startup. They'll 71 | share every defeat with you and celebrate every success. They'll help you 72 | understand your own ideas better by offering a different perspective. They'll be 73 | the single most important decision you make during the tenure of your startup, 74 | so choose wisely and with extreme care. 75 | -------------------------------------------------------------------------------- /test_projects/mojombo/_posts/2008-11-17-blogging-like-a-hacker.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Blogging Like a Hacker 4 | --- 5 | 6 | {{ page.title }} 7 | ================ 8 | 9 |

17 Nov 2008 - San Francisco

10 | 11 | Back in 2000, when I thought I was going to be a professional writer, I spent 12 | hours a day on LiveJournal doing writing practice with other aspiring poets and 13 | authors. Since then I've blogged at three different domains about web standards, 14 | print design, photography, Flash, illustration, information architecture, 15 | ColdFusion, package management, PHP, CSS, advertising, Ruby, Rails, and Erlang. 16 | 17 | I love writing. I get a kick out of sharing my thoughts with others. The act of 18 | transforming ideas into words is an amazingly efficient way to solidify and 19 | refine your thoughts about a given topic. But as much as I enjoy blogging, I 20 | seem to be stuck in a cycle of quitting and starting over. Before starting the 21 | current iteration, I resolved to do some introspection to determine the factors 22 | that were leading to this destructive pattern. 23 | 24 | I already knew a lot about what I *didn't* want. I was tired of complicated 25 | blogging engines like WordPress and Mephisto. I wanted to write great posts, not 26 | style a zillion template pages, moderate comments all day long, and constantly 27 | lag behind the latest software release. Something like Posterous looked 28 | attractive, but I wanted to style my blog, and it needed to be hosted at the 29 | domain of my choosing. For the same reason, other hosted sites (wordpress.com, 30 | blogger.com) were disqualified. There are a few people directly using GitHub as 31 | a blog (which is very cool), but that's a bit too much of an impedance mismatch 32 | for my tastes. 33 | 34 | On Sunday, October 19th, I sat down in my San Francisco apartment with a glass 35 | of apple cider and a clear mind. After a period of reflection, I had an idea. 36 | While I'm not specifically trained as an author of prose, I *am* trained as an 37 | author of code. What would happen if I approached blogging from a software 38 | development perspective? What would that look like? 39 | 40 | First, all my writing would be stored in a Git repository. This would ensure 41 | that I could try out different ideas and explore a variety of posts all from the 42 | comfort of my preferred editor and the command line. I'd be able to publish a 43 | post via a simple deploy script or post-commit hook. Complexity would be kept to 44 | an absolute minimum, so a static site would be preferable to a dynamic site that 45 | required ongoing maintenance. My blog would need to be easily customizable; 46 | coming from a graphic design background means I'll always be tweaking the site's 47 | appearance and layout. 48 | 49 | Over the last month I've brought these concepts to fruition and I'm pleased to 50 | announce [Jekyll](http://github.com/mojombo/jekyll). Jekyll is a simple, blog 51 | aware, static site generator. It takes a template directory (representing the 52 | raw form of a website), runs it through Textile and Liquid converters, and spits 53 | out a complete, static website suitable for serving with Apache or your favorite 54 | web server. If you're reading this on the website 55 | (http://tom.preston-werner.com), you're seeing a Jekyll generated blog! 56 | 57 | To understand how this all works, open up my [TPW](http://github.com/mojombo/tpw) 58 | repo in a new browser window. I'll be referencing the code there. 59 | 60 | Take a look at 61 | [index.html](http://github.com/mojombo/tpw/tree/master/index.html). This file 62 | represents the homepage of the site. At the top of the file is a chunk of YAML 63 | that contains metadata about the file. This data tells Jekyll what layout to 64 | give the file, what the page's title should be, etc. In this case, I specify 65 | that the "default" template should be used. You can find the layout files in the 66 | [_layouts](http://github.com/mojombo/tpw/tree/master/_layouts) directory. If you 67 | open 68 | [default.html](http://github.com/mojombo/tpw/tree/master/_layouts/default.html) 69 | you can see that the homepage is constructed by wrapping index.html with this 70 | layout. 71 | 72 | You'll also notice Liquid templating code in these files. 73 | [Liquid](http://www.liquidmarkup.org/) is a simple, extensible templating 74 | language that makes it easy to embed data in your templates. For my homepage I 75 | wanted to have a list of all my blog posts. Jekyll hands me a Hash containing 76 | various data about my site. A reverse chronological list of all my blog posts 77 | can be found in site.posts. Each post, in turn, contains various 78 | fields such as title and date. 79 | 80 | Jekyll gets the list of blog posts by parsing the files in the 81 | [_posts](http://github.com/mojombo/tpw/tree/master/_posts) directory. Each post's 82 | filename contains the publishing date and slug (what shows up in the URL) that 83 | the final HTML file should have. Open up the file corresponding to this blog 84 | post: 85 | [2008-11-17-blogging-like-a-hacker.textile](http://github.com/mojombo/tpw/tree/master/_posts/2008-11-17-blogging-like-a-hacker.textile). 86 | GitHub renders textile files by default, so to better understand the file, click 87 | on the 88 | [raw](http://github.com/mojombo/tpw/tree/master/_posts/2008-11-17-blogging-like-a-hacker.textile?raw=true) 89 | view to see the original file. Here I've specified the post layout. 90 | If you look at that file you'll see an example of a nested layout. Layouts can 91 | contain other layouts allowing you a great deal of flexibility in how pages are 92 | assembled. In my case I use a nested layout in order to show related posts for 93 | each blog entry. The YAML also specifies the post's title which is then embedded 94 | in the post's body via Liquid. 95 | 96 | Posts are handled in a special way by Jekyll. The date you specify in the 97 | filename is used to construct the URL in the generated site. This post, for 98 | instance, ends up at 99 | http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html. 100 | 101 | Files that do not reside in directories prefixed with an underscore are mirrored 102 | into a corresponding directory structure in the generated site. If a file does 103 | not have a YAML preface, it is not run through the Liquid interpreter. Binary 104 | files are copied over unmodified. 105 | 106 | In order to convert your raw site into the finished version, you simply run: 107 | 108 |
$ jekyll /path/to/raw/site
109 | /path/to/place/generated/site
110 | 111 | Jekyll is still a very young project. I've only developed the exact 112 | functionality that I've needed. As time goes on I'd like to see the project 113 | mature and support additional features. If you end up using Jekyll for your own 114 | blog, drop me a line and let me know what you'd like to see in future versions. 115 | Better yet, fork the project over at GitHub and hack in the features yourself! 116 | 117 | I've been living with Jekyll for just over a month now. I love it. Driving the 118 | development of Jekyll based on the needs of my blog has been very rewarding. I 119 | can edit my posts in TextMate, giving me automatic and competent spell checking. 120 | I have immediate and first class access to the CSS and page templates. 121 | Everything is backed up on GitHub. I feel a lightness now when I'm writing a 122 | post. The system is simple enough that I can keep the entire conversion process 123 | in my head. The distance from my brain to my blog has shrunk, and, in the end, I 124 | think that will make me a better author. 125 | -------------------------------------------------------------------------------- /test_projects/mojombo/_posts/2010-05-11-tomdoc-reasonable-ruby-documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: TomDoc - Reasonable Ruby Documentation 4 | --- 5 | 6 | {{ page.title }} 7 | ================ 8 | 9 |

11 May 2016 - San Francisco

10 | 11 | [RDoc](http://rdoc.rubyforge.org) is an abomination. It's ugly to read in plain 12 | text, requires the use of the inane :nodoc: tag to prevent private method 13 | documentation from showing up in final rendering, and does nothing to encourage 14 | complete or unambiguous documentation of classes, methods, or parameters. 15 | [YARD](http://yardoc.org) is much better but goes too far in the other direction 16 | (and still doesn't look good in plain text). Providing an explicit way to 17 | specify parameters and types is great, but having to remember a bunch of strict 18 | tag names in order to be compliant is not a good way to encourage coders to 19 | write documentation. And again we see a `@private` tag that's necessary to hide 20 | docs from the final render. 21 | 22 | Three years ago, after suffering with these existing documentation formats for 23 | far too long, I started using my own documentation format. It looked a bit like 24 | RDoc but had a set of conventions for specifying parameters, return values, and 25 | the expected types. It used plain language and full sentences so that a human 26 | could read and understand it without having to parse machine-oriented tags or 27 | crufty markup. I called this format TomDoc, because if Linus can name stuff 28 | after himself, then why can't I? 29 | 30 | After years in the making, TomDoc is finally a well specified documentation 31 | format. You can find the full spec at [http://tomdoc.org](http://tomdoc.org). 32 | 33 | But enough talk. Here's a sample of what a TomDoc'd method might look like: 34 | 35 | ``` ruby 36 | # Public: Duplicate some text an abitrary number of times. 37 | # 38 | # text - The String to be duplicated. 39 | # count - The Integer number of times to duplicate the text. 40 | # 41 | # Examples 42 | # 43 | # multiplex('Tom', 4) 44 | # # => 'TomTomTomTom' 45 | # 46 | # Returns the duplicated String. 47 | def multiplex(text, count) 48 | text * count 49 | end 50 | ``` 51 | 52 | At first glance you'll notice a few things. First, and most important, is that 53 | the documentation looks nice in plain text. When I'm working on a project, I 54 | need to be able to scan and read method documentation quickly. Littering the 55 | docs with tags and markup (especially HTML markup) is not acceptable. Code 56 | documentation should be optimized for human consumption. Second, all parameters 57 | and return values, and their expected types are specified. Types are generally 58 | denoted by class name. Because Ruby is so flexible, you are not constrained by a 59 | rigid type declaration syntax and are free to explain precisely how the expected 60 | types may vary under different circumstances. Finally, the basic layout is 61 | designed to be easy to remember. Once you commit a few simple conventions to 62 | memory, writing documentation becomes second nature, with all of the tricky 63 | decision making already done for you. 64 | 65 | Today's Ruby libraries suffer deeply from haphazard versioning schemes. Even 66 | RubyGems itself does not follow a sane or predictable versioning pattern. This 67 | lack of discipline stems from the absence of well defined Public APIs. TomDoc 68 | attempts to solve this problem by making it simple to define an unambiguous 69 | Public API for your library. Instead of assuming that all classes and methods 70 | are intended for public consumption, TomDoc makes the Public API opt-in. To 71 | denote that something is public, all you have to do is preface the main 72 | description with "Public:". By forcing you to explicitly state that a class or 73 | method is intended for public consumption, a deliberate and thoughtful Public 74 | API is automatically constructed that can inform disciplined version changes 75 | according to the tenets of [Semantic Versioning](http://semver.org). In 76 | addition, the prominent display of "Public" in a method description ensures that 77 | developers are made aware of the sensitive nature of the method and do not 78 | carelessly change the signature of something in the Public API. 79 | 80 | Once a Public API has been established, some very exciting things become 81 | possible. We're currently working on a processing tool that will render TomDoc 82 | into various forms (terminal, HTML, etc). If you run this tool on a library, 83 | you'll get a printout of the Public API documentation. You can publish this 84 | online so that others have easy access to it. When you roll a new version of the 85 | library, you can run the tool again, giving it a prior version as a base, and 86 | have it automatically display only the methods that have changed. This diff will 87 | be extremely useful for users while they upgrade to the new version (or so they 88 | can evaluate whether an upgrade is warranted)! 89 | 90 | While I've been using various nascent forms of TomDoc for several years, we're 91 | just now starting to adopt it for everything we do at GitHub. Now that I've 92 | formalized the spec it will be easy for the entire team to write compliant 93 | TomDoc. The goal is to have every class, method, and accessor of every GitHub 94 | library documented. In the future, once we have proper tooling, we'd even like 95 | to create a unit test that will fail if anything is missing documentation. 96 | 97 | TomDoc is still a rough specification so I'm initially releasing it as 0.9.0. 98 | Over the coming months I'll make any necessary changes to address user concerns 99 | and release a 1.0.0 version once things have stabilized. If you'd like to 100 | suggest changes, please open an issue on the [TomDoc GitHub 101 | repository](http://github.com/mojombo/tomdoc). 102 | -------------------------------------------------------------------------------- /test_projects/mojombo/_posts/2010-08-23-readme-driven-development.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Readme Driven Development 4 | --- 5 | 6 | {{ page.title }} 7 | ================ 8 | 9 |

23 August 2010 - San Francisco

10 | 11 | I hear a lot of talk these days about TDD and BDD and Extreme Programming and SCRUM and stand up meetings and all kinds of methodologies and techniques for developing better software, but it's all irrelevant unless the software we're building meets the needs of those that are using it. Let me put that another way. A perfect implementation of the wrong specification is worthless. By the same principle a beautifully crafted library with no documentation is also damn near worthless. If your software solves the wrong problem or nobody can figure out how to use it, there's something very bad going on. 12 | 13 | Fine. So how do we solve this problem? It's easier than you think, and it's important enough to warrant its very own paragraph. 14 | 15 | Write your Readme first. 16 | 17 | First. As in, before you write any code or tests or behaviors or stories or ANYTHING. I know, I know, we're programmers, dammit, not tech writers! But that's where you're wrong. Writing a Readme is absolutely essential to writing good software. Until you've written about your software, you have no idea what you'll be coding. Between The Great Backlash Against Waterfall Design and The Supreme Acceptance of Agile Development, something was lost. Don't get me wrong, waterfall design takes things way too far. Huge systems specified in minute detail end up being the WRONG systems specified in minute detail. We were right to strike it down. But what took its place is too far in the other direction. Now we have projects with short, badly written, or entirely missing documentation. Some projects don't even have a Readme! 18 | 19 | This is not acceptable. There must be some middle ground between reams of technical specifications and no specifications at all. And in fact there is. That middle ground is the humble Readme. 20 | 21 | It's important to distinguish Readme Driven Development from Documentation Driven Development. RDD could be considered a subset or limited version of DDD. By restricting your design documentation to a single file that is intended to be read as an introduction to your software, RDD keeps you safe from DDD-turned-waterfall syndrome by punishing you for lengthy or overprecise specification. At the same time, it rewards you for keeping libraries small and modularized. These simple reinforcements go a long way towards driving your project in the right direction without a lot of process to ensure you do the right thing. 22 | 23 | By writing your Readme first you give yourself some pretty significant advantages: 24 | 25 | * Most importantly, you're giving yourself a chance to think through the project without the overhead of having to change code every time you change your mind about how something should be organized or what should be included in the Public API. Remember that feeling when you first started writing automated code tests and realized that you caught all kinds of errors that would have otherwise snuck into your codebase? That's the exact same feeling you'll have if you write the Readme for your project before you write the actual code. 26 | 27 | * As a byproduct of writing a Readme in order to know what you need to implement, you'll have a very nice piece of documentation sitting in front of you. You'll also find that it's much easier to write this document at the beginning of the project when your excitement and motivation are at their highest. Retroactively writing a Readme is an absolute drag, and you're sure to miss all kinds of important details when you do so. 28 | 29 | * If you're working with a team of developers you get even more mileage out of your Readme. If everyone else on the team has access to this information before you've completed the project, then they can confidently start work on other projects that will interface with your code. Without any sort of defined interface, you have to code in serial or face reimplementing large portions of code. 30 | 31 | * It's a lot simpler to have a discussion based on something written down. It's easy to talk endlessly and in circles about a problem if nothing is ever put to text. The simple act of writing down a proposed solution means everyone has a concrete idea that can be argued about and iterated upon. 32 | 33 | Consider the process of writing the Readme for your project as the true act of creation. This is where all your brilliant ideas should be expressed. This document should stand on its own as a testament to your creativity and expressiveness. The Readme should be the single most important document in your codebase; writing it first is the proper thing to do. 34 | 35 | -- 36 | 37 | [Discuss this post on Hacker News](http://news.ycombinator.com/item?id=1627246) -------------------------------------------------------------------------------- /test_projects/mojombo/_posts/2010-10-18-optimize-for-happiness.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Optimize for Happiness 4 | --- 5 | 6 | {{ page.title }} 7 | ================ 8 | 9 |

18 October 2010 - San Francisco

10 | 11 | Two days ago I had the pleasure of speaking at Startup School, a yearly conference on entrepreneurism put on by the great folks at Y Combinator. Never before have I see such a high concentration of smart ambitious people in one place. 12 | 13 | You can watch the recording of my thirty minute slot on Youtube: 14 | 15 |
16 | 17 | Since I only had about 25 minutes for the talk and 5 minutes for questions, I wanted to expand upon and clarify some of the ideas I introduced during the talk and then make myself available for additional questions. So today (Monday, 18 October 2010) I'll be answering any questions you have via Hacker News: 18 | 19 |
Ask me a question on HN!
20 | 21 | The very first commit to GitHub was made exactly three years ago tomorrow. In that time our team of thirteen has signed up over 420,000 developers and now hosts 1.3 million Git repositories, making us the largest code host on the planet. And we've done all of this without ever taking a dime of funding from outside the company. In fact, even within the company we only invested a few thousand dollars out of our own pockets during the first months to cover legal fees. 22 | 23 | During the presentation I talk about a choice between optimizing for happiness and optimizing for money. When I say "optimizing for money" I mean following the traditional venture capital route of raising a ton of money to stash in your bank account and going for a huge exit. The unfortunate reality of this approach is that for aspiring entrepreneurs that are not well connected to the VC world, it can take an extraordinary amount of time and effort to raise that money. Even if you are able to raise capital, you are suddenly responsible to your investors and will need to align your interests with theirs. 24 | 25 | In a world dominated by news about Facebook, Apple, Google, YouTube, Zappos, and other companies heavily funded by venture capital, it's easy to forget that you can still build a highly profitable business with significant impact on a global market without having to first spend three months on Sand Hill Road asking for permission to build your product. 26 | 27 | The infrastructure components necessary to run an internet business are finally cheap enough that you can get started without a huge up-front investment. In the months that you would traditionally spend in glass-walled conference rooms you can now build a sophisticated prototype of your product and start getting users signed up and engaging you with useful feedback. 28 | 29 | This is what I mean by optimizing for happiness: I'm a hacker; I'm happy when I'm building things of value, not when I'm writing a business plan filled with make believe numbers. 30 | 31 | When Chris and I started GitHub, I was working full time at Powerset and Chris was doing consulting work and plugging away on a product of his own. GitHub became the leisure activity that I worked on when I got home from the office. I could craft it however I pleased, and there was nobody telling me what to do. This feeling of control and ownership of something you own is intoxicating. 32 | 33 | Within three months we had a simple product and moved into private beta. In six months we launched to the public and started charging for private plans. We've been profitable every month since public launch except for one (in which we hired two new employees at once). We did this by making a paycheck via other means until GitHub was generating enough revenue to support us full time at about 2/3 of what we were accustomed to making. We then raised our salaries over the next months when we hit specific revenue goals that allowed us to remain profitable. This happened about one year after inception. 34 | 35 | A side effect of bootstrapping a sustainable company is what I like to call infinite runway. This is another element of optimizing for happiness. With venture backed endeavors you generally find that during the first several years the numbers in your bank account are perpetually decreasing, giving your company an expiration date. Your VCs have encouraged you to grow fast and spend hard, which makes perfect sense for them, but not necessary for you. Not if you're trying to optimize for happiness. 36 | 37 | VCs want to see quick success or quick failure. They are optimizing for money. There's nothing wrong with that as long as you want the same things they do. But if you're like me, then you care more about building a kickass product than you do about having a ten figure exit. If that's true, then maybe you should be optimizing for happiness. One way to do this is by bootstrapping a sustainable business with infinite runway. When there are fewer potentially catastrophic events on the horizon, you'll find yourself smiling a lot more often. 38 | 39 | The ironic thing about bootstrapping and venture capital is that once you demonstrate some success, investors will come to YOU. When this happens you will be in a much better place to make a more reasoned choice about taking on additional capital and all the complexities that come with it. Talking to VCs with some leverage in your back pocket is an entirely different game from throwing yourself in front of a conference table full of general partners and trying to persuade them that you're worth their time and money. Power is happiness. 40 | 41 | There are other really great things you can do when you optimize for happiness. You can throw away things like financial projections, hard deadlines, ineffective executives that make investors feel safe, and everything that hinders your employees from building amazing products. 42 | 43 | At GitHub we don't have meetings. We don't have set work hours or even work days. We don't keep track of vacation or sick days. We don't have managers or an org chart. We don't have a dress code. We don't have expense account audits or an HR department. 44 | 45 | We pay our employees well and give them the tools they need to do their jobs as efficiently as possible. We let them decide what they want to work on and what features are best for the customers. We pay for them to attend any conference at which they've gotten a speaking slot. If it's in a foreign country, we pay for another employee to accompany them because traveling alone sucks. We show them the profit and loss statements every month. We expect them to be responsible. 46 | 47 | We make decisions based on the merits of the arguments, not on who is making them. We strive every day to be better than we were the day before. 48 | 49 | We hold our board meetings in bars. 50 | 51 | We do all this because we're optimizing for happiness, and because there's nobody to tell us that we can't. 52 | 53 |
Ask me a question on HN!
54 | -------------------------------------------------------------------------------- /test_projects/mojombo/_posts/2010-12-11-designer-architect-developer.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Designer, Architect, Developer 4 | --- 5 | 6 | {{ page.title }} 7 | ================ 8 | 9 |

11 Dec 2010 - San Francisco

10 | 11 | Over the last six years I’ve bootstrapped three successful enterprises (Cube6 Media, Gravatar, and GitHub) and failed to gain traction with a handful of others. After a lot of thought and reflections on these experiences, I’ve identified three major skills that should be present in order to best build a successful web application. These roles can be loosely defined as the Designer, the Architect, and the Developer. 12 | 13 | In college I spent a lot of time in the campus dark room dipping rolls of film and sheets of paper into various chemical baths beneath a dim red light. The most interesting part, though, was mounting the negative into the projector and exposing the photo paper. Every time I turned on the bright light of the projector I was reminded of a saying that has stuck with me ever since: “A photograph is nothing more than an image created by light.” Think about that for a second. The only way the photograph, and hence, the viewer, interact with the original subject is via the light that was captured. None of the fancy flashes, soft boxes, bounces, umbrellas, or backdrops mean a thing if the light they produce or redirect is in the wrong place. If the light is bad, the photograph is bad. 14 | 15 | I think the same concept holds true for web applications. Adapting the saying for our own situation, I would say: “A web application is nothing more than an experience created by design.” Users can’t see what technology you use or whether you follow an agile development process or not. All they experience is what’s on the screen. It can’t be confusing, it can’t look amateur, and it can’t have spelling errors. If the UX is bad, the web application is bad. It’s that simple. 16 | 17 | The way you get good UX is by having a good designer. Someone on the team must be skilled not only in making things pretty, but in making them usable as well. Without a good UX/visual design, you may as well not even bother. It’s impossible to stress how important this is. 18 | 19 | Design comes first. It defines what you will build. Once you have an idea of what you’re creating, you need to figure out how to make it happen. That’s where the Architect comes in. 20 | 21 | With the recent explosion of open source solutions to common problems like databases, web frameworks, job processors, messaging systems, etc, you need a team member that has a broad understanding of the technology landscape. The choices you make early on will impact your company for many years, and the wrong choices can spell disaster. The role of the Architect is to choose the best tools for the job, and to decide when new tools need to be created. 22 | 23 | The Architect must also be ready to scale any piece of the site when you start attracting users. There’s a fine line between premature optimization and crumbling under the wave of thousands of new signups. A good architect will always be one step ahead of the curve, laying the groundwork for future scaling needs just before they are needed. 24 | 25 | Design and architecture dictate what you build and how you build it, but without someone to do the construction, you’re dead in the water. The role of the Developer is to turn the wishes of the Designer into reality while staying within the constraints that the Architect has put forth. In addition, the Developer has to ensure that the codebase remains healthy and protect against technical debt. Sloppy development up front means a huge amount of wasted effort later on. 26 | 27 | The three roles of the Designer, the Architect, and the Developer may reside in a single person, but it’s much more common to see groups of two or three people satisfy all these skills. In fact, the best founding teams are those where everyone fills some combination of roles. This fosters an environment of friendly argument that leads to better decisions. 28 | 29 | But whatever you do, make sure your team fills all of these roles. Once you do, executing on your idea should come easily! 30 | -------------------------------------------------------------------------------- /test_projects/mojombo/_posts/2011-05-03-rejected-bio-from-the-setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Rejected Bio from The Setup 4 | --- 5 | 6 | {{ page.title }} 7 | ================ 8 | 9 |

03 May 2011 - San Francisco

10 | 11 | Yesterday, [the autobiographical post I wrote for The 12 | Setup](http://tom.preston-werner.usesthis.com/) went live. I wrote that post 13 | over a year ago and then entered into an epic battle with 14 | [@waferbaby](http://twitter.com/#!/waferbaby) about the length of my "Who are 15 | you, and what do you do?" section. He said it was too long. I said it could 16 | not be shortened. And so the post sat for a year, collecting dust, neither of 17 | us prepared to back down. 18 | 19 | About a month ago I decided that it was foolish to let the words I had written rot on my hard drive and so I did the only thing I knew how to do: overreact. So I cut the original nine-hundred words of my bio down to fourteen words and resubmitted it to Daniel. Those are the words you see in the post now. 20 | 21 | For your pleasure, here is the original bio in its full, unabridged glory. 22 | 23 |
24 | 25 | My name is Tom Preston-Werner. I find that the hyphenated last name 26 | makes me sound distinguished and worth listening to. I grew up three 27 | decades ago in a small city in Iowa along the Mississippi, which means 28 | I shucked a lot of corn and know exactly how many mosquitos will land 29 | on your arm should you hold it still for ten minutes at dusk on the 30 | muggiest day of the summer. As an aspiring theoretical particle 31 | physicist, I worked my way through entire shelves of scientific 32 | literature from the public library, desperately wanting to understand 33 | the bewildering mathematics that littered the pages like so many 34 | leaves on the bottom of that morning's cup of green tea. I searched in 35 | vain for instructors or classmates that could provide me with the 36 | insight necessary to comprehend the true meaning of Heisenberg's 37 | Uncertainty Principle, but all I found were underpaid math teachers 38 | and disillusioned "students" in search of their next smoke break. 39 | After obsessing over US News' Best Colleges reports for months I 40 | finally chose and was accepted to Harvey Mudd, a tiny engineering 41 | school in California famous for assigning the greatest number of hours 42 | of homework per night. This sounded just perfect to me. Finally a 43 | place I could bring up the EPR Paradox and not be immediately 44 | stigmatized as "that science weirdo with the hilariously thick glasses 45 | and unfortunate hairdo." 46 | 47 | Mudd did not disappoint. But now I had the opposite problem. In order 48 | to properly understand particle physics, you must have a deep and 49 | profound love of math. You have to be so comfortable with abstract 50 | concepts that even Picasso would be jealous. Ironically, in order to 51 | grasp the fundamental reality of our universe, you must forget about 52 | the "reality" of everyday life and start living in a world comprised 53 | of eigenvectors, Hilbert spaces, and Planck's constant. This was a 54 | leap I could not make. I like math, but I'm too easily distracted by 55 | macroscopic reality to make it my profession. 56 | 57 | Once I accepted that I would never spend late nights poring over 58 | bubble chamber printouts at Fermilab, it became obvious that I was 59 | destined to enter computer science. I started programming in BASIC on 60 | a TRS-80 that my dad bought from Radio Shack when I was 8 years old. 61 | Since then, I'd learned to love the discipline and creativity involved 62 | in making a machine do my bidding. It was like having a super-obedient 63 | but annoyingly logical little brother. He'll do anything you want as 64 | long as you tell him in precise and unambiguous language. The best 65 | thing is, the feedback is immediate. In physics, it can take twenty 66 | years to prove that a single esoteric particle even exists. When 67 | you're writing a program that displays the number of electrons in each 68 | of the shells around the nucleus of every element, the feedback is 69 | immediate and intoxicating. With just a few keystrokes, the world is 70 | changed forever. Try to get that kind of rush even once in a lifetime 71 | as a theoretical particle physicist. I dare you. 72 | 73 | In 1999, after two years of college, I dropped out of Harvey Mudd to 74 | join a startup with some friends that were graduating. It was the end 75 | of the first dot-com bubble and I thought I could strike it rich, 76 | right then and there. Sadly, like so many startups of the day, we 77 | never accomplished what we envisioned and I ended up bouncing between 78 | jobs and consulting gigs for six years until I found myself in San 79 | Francisco. If Harvey Mudd was my mecca for physicists, then San 80 | Francisco was my mecca for programmers. Where else can you be grabbing 81 | lunch at a taqueria and overhear a group at the next table discussing 82 | the finer points of optimizing C code to run on an embedded processor? 83 | 84 | I moved to San Francisco to take a job as a Ruby developer with a 85 | Wikipedia search engine called Powerset. I also began attending Ruby 86 | meetups and drinking with local software developers. There are a lot 87 | of talented people in the Bay Area and I wanted to meet them all. 88 | Within the Ruby community, a distributed version control system called 89 | Git was starting to get some attention. It was a really cool way of 90 | working with other people on code, but there wasn't an easy way to get 91 | up and running with a group of developers. Along with cofounders Chris 92 | Wanstrath and PJ Hyett (who I met at the Ruby meetups) I started a 93 | company called GitHub that would address this problem and make it dead 94 | simple to share Git repositories and collaborate on code with other 95 | developers. 96 | 97 | At first, we worked on GitHub on the side, putting in time on evenings 98 | and weekends. After six months we launched the site to the public and 99 | started charging. Not long after that, Powerset was acquired by 100 | Microsoft and I was faced with a choice: stay on as a Microsoft 101 | employee with a big retention bonus and give up GitHub or turn down 102 | the Microsoft money and quit Powerset to work on GitHub full-time. You 103 | can read more about this saga in my blog post entitled [How I Turned 104 | Down $300,000 from Microsoft to go Full-Time on 105 | GitHub](http://tom.preston-werner.com/2008/10/18/how-i-turned-down-300k.html). 106 | I think I made the right decision. 107 | 108 | Today GitHub has twenty-nine employees and more than 730,000 users with over 109 | 2,000,000 repositories. We're growing fast, and I'm having the time of 110 | my life! -------------------------------------------------------------------------------- /test_projects/mojombo/_posts/2011-11-22-open-source-everything.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Open Source (Almost) Everything 4 | --- 5 | 6 | {{ page.title }} 7 | ================ 8 | 9 |

22 Nov 2011 - San Francisco

10 | 11 | When Chris and I first started working on GitHub in late 2007, we split the work into two parts. Chris worked on the Rails app and I worked on Grit, the first ever Git bindings for Ruby. After six months of development, Grit had become complete enough to power GitHub during our public launch of the site and we were faced with an interesting question: 12 | 13 | Should we open source Grit or keep it proprietary? 14 | 15 | Keeping it private would provide a higher hurdle for competing Ruby-based Git hosting sites, giving us an advantage. Open sourcing it would mean thousands of people worldwide could use it to build interesting Git tools, creating an even more vibrant Git ecosystem. 16 | 17 | After a small amount of debate we decided to open source Grit. I don't recall the specifics of the conversation but that decision nearly four years ago has led to what I think is one of our most important core values: open source (almost) everything. 18 | 19 | Why is it awesome to open source (almost) everything? 20 | ----------------------------------------------------- 21 | 22 | If you do it right, open sourcing code is **great advertising** for you and your company. At GitHub we like to talk publicly about libraries and systems we've written that are still closed but destined to become open source. This technique has several advantages. It helps determine what to open source and how much care we should put into a launch. We recently open sourced Hubot, our chat bot, to widespread delight. Within two days it had 500 watchers on GitHub and 409 upvotes on Hacker News. This translates into goodwill for GitHub and more superfans than ever before. 23 | 24 | If your code is popular enough to attract outside contributions, you will have created a **force multiplier** that helps you get more work done faster and cheaper. More users means more use cases being explored which means more robust code. Our very own [resque](https://github.com/defunkt/resque) has been improved by 115 different individuals outside the company, with hundreds more providing 3rd-party plugins that extend resque's functionality. Every bug fix and feature that you merge is time saved and customer frustration avoided. 25 | 26 | Smart people like to hang out with other smart people. Smart developers like to hang out with smart code. When you open source useful code, you **attract talent**. Every time a talented developer cracks open the code to one of your projects, you win. I've had many great conversations at tech conferences about my open source code. Some of these encounters have led to ideas that directly resulted in better solutions to problems I was having with my projects. In an industry with such a huge range of creativity and productivity between developers, the right eyeballs on your code can make a big difference. 27 | 28 | If you're hiring, **the best technical interview possible** is the one you don't have to do because the candidate is already kicking ass on one of your open source projects. Once technical excellence has been established in this way, all that remains is to verify cultural fit and convince that person to come work for you. If they're passionate about the open source code they've been writing, and you're the kind of company that cares about well-crafted code (which clearly you are), that should be simple! We hired [Vicent Martí](https://github.com/tanoku) after we saw him doing stellar work on [libgit2](https://github.com/libgit2/libgit2), a project we're spearheading at GitHub to extract core Git functionality into a standalone C library. No technical interview was necessary, Vicent had already proven his skills via open source. 29 | 30 | Once you've hired all those great people through their contributions, dedication to open source code is an amazingly effective way to **retain that talent**. Let's face it, great developers can take their pick of jobs right now. These same developers know the value of coding in the open and will want to build up a portfolio of projects they can show off to their friends and potential future employers. That's right, a paradox! In order to keep a killer developer happy, you have to help them become more attractive to other employers. But that's ok, because that's exactly the kind of developer you want to have working for you. So relax and let them work on open source or they'll go somewhere else where they can. 31 | 32 | When I start a new project, I assume it will eventually be open sourced (even if it's unlikely). This mindset leads to **effortless modularization**. If you think about how other people outside your company might use your code, you become much less likely to bake in proprietary configuration details or tightly coupled interfaces. This, in turn, leads to cleaner, more maintainable code. Even internal code should pretend to be open source code. 33 | 34 | Have you ever written an amazing library or tool at one job and then left to join another company only to rewrite that code or remain miserable in its absence? I have, and it sucks. By getting code out in the public we can drastically **reduce duplication of effort**. Less duplication means more work towards things that matter. 35 | 36 | Lastly, **it's the right thing to do**. It's almost impossible to do anything these days without directly or indirectly executing huge amounts of open source code. If you use the internet, you're using open source. That code represents millions of man-hours of time that has been spent and then given away so that everyone may benefit. We all enjoy the benefits of open source software, and I believe we are all morally obligated to give back to that community. If software is an ocean, then open source is the rising tide that raises all ships. 37 | 38 | Ok, then what shouldn't I open source? 39 | -------------------------------------- 40 | 41 | That's easy. Don't open source anything that represents core business value. 42 | 43 | Here are some examples of what we don't open source and why: 44 | 45 | * Core GitHub Rails app (easier to sell when closed) 46 | * The Jobs Sinatra app (specially crafted integration with github.com) 47 | 48 | Here are some examples of things we do open source and why: 49 | 50 | * Grit (general purpose Git bindings, useful for building many tools) 51 | * Ernie (general purpose BERT-RPC server) 52 | * Resque (general purpose job processing) 53 | * Jekyll (general purpose static site generator) 54 | * Gollum (general purpose wiki app) 55 | * Hubot (general purpose chat bot) 56 | * Charlock_Holmes (general purpose character encoding detection) 57 | * Albino (general purpose syntax highlighting) 58 | * Linguist (general purpose filetype detection) 59 | 60 | Notice that everything we keep closed has specific business value that could be compromised by giving it away to our competitors. Everything we open is a general purpose tool that can be used by all kinds of people and companies to build all kinds of things. 61 | 62 | What is the One True License? 63 | ----------------------------- 64 | 65 | I prefer the MIT license and almost everything we open source at GitHub carries this license. I love this license for several reasons: 66 | 67 | * It's short. Anyone can read this license and understand exactly what it means without wasting a bunch of money consulting high-octane lawyers. 68 | 69 | * Enough protection is offered to be relatively sure you won't sue me if something goes wrong when you use my code. 70 | 71 | * Everyone understands the legal implications of the MIT license. Weird licenses like the WTFPL and the Beer license pretend to be the "ultimate in free licenses" but utterly fail at this goal. These fringe licenses are too vague and unenforceable to be acceptable for use in some companies. On the other side, the GPL is too restrictive and dogmatic to be usable in many cases. I want everyone to benefit from my code. Everyone. That's what Open should mean, and that's what Free should mean. 72 | 73 | Rad, how do I get started? 74 | -------------------------- 75 | 76 | Easy, just flip that switch on your GitHub repository from private to public and tell the world about your software via your blog, Twitter, Hacker News, and over beers at your local pub. Then sit back, relax, and enjoy being part of something big. 77 | 78 | [Discuss this post on Hacker News](http://news.ycombinator.com/item?id=3267432) 79 | -------------------------------------------------------------------------------- /test_projects/mojombo/_posts/2014-04-21-farewell-github-hello-immersive-computing.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Farewell GitHub, Hello Immersive Computing 4 | --- 5 | 6 | {{ page.title }} 7 | ================ 8 | 9 |

21 Apr 2014 - New York City

10 | 11 | Today is my last day at GitHub. Recent events have given me a lot of time to 12 | reflect on what's important to me, and I've decided to switch gears and focus on 13 | building something from scratch again. Since visiting the Oculus VR team at 14 | their office three months ago, I've come to believe that immersive computing 15 | (aka virtual reality) is poised to rival the personal computer, the web, social 16 | networking, and mobile devices in its impact. While the timing is more abrupt 17 | than I had intended, with everything that's happened, I think now is the right 18 | time to do this, and I'd like to explain why. 19 | 20 | First, I want to address the serious accusations that were made against me and 21 | my family over the past month. With every decision I made at GitHub and in every 22 | interaction I had with employees, I tried to treat people better than they 23 | expected and to resolve conflict with empathy. Despite that, I've made mistakes, 24 | and I am deeply sorry to anyone who was hurt by those mistakes. It devastates me 25 | to know that I missed the mark, and I will strive to do better, every day. 26 | 27 | That said, I want to be very clear about one thing: neither my wife, Theresa, 28 | nor I have ever engaged in gender-based harassment or discrimination. The 29 | results of GitHub's independent investigation unequivocally confirm this and we 30 | are prepared to fight any further false claims on this matter to the full extent 31 | of the law. I believe in diversity and equality for all people in all 32 | professions, especially the tech sector. It's immensely important to me and I 33 | will continue to do my very best to further that belief. 34 | 35 | Unfortunately, the investigation and all the attention surrounding it have me 36 | concerned that remaining at GitHub would be a distraction for both me and the 37 | company. I'm incredibly proud of what I've helped build at GitHub and I don't 38 | want the events of the past month to jeopardize that. I care too much about the 39 | company and the people here to let that happen. The GitHub team is incredibly 40 | strong, with fierce vision, and I have no doubt they will continue to 41 | revolutionize software development for decades to come. Founding and building 42 | GitHub has been the greatest adventure of my life. I've been so lucky to be on 43 | this journey with such amazing, helpful, talented, and real people. I'm going to 44 | miss working with such a great team, but I'm also insanely excited about the 45 | future. 46 | 47 | Since the early days of GitHub, I've wanted to create a different kind of 48 | business. One that was [Optimized for 49 | Happiness](http://tom.preston-werner.com/2010/10/18/optimize-for-happiness.html) 50 | and built atop a [Framework of 51 | Happiness](https://www.youtube.com/watch?v=i0FzgvYxdvk). One where great people 52 | could work on hard problems together to create unbelievably good products. I 53 | believe I was able to achieve a great deal of success with that model at GitHub, 54 | even if things didn't always go perfectly according to plan. All of this has 55 | been a tremendous learning experience for me. 56 | 57 | Last January I stepped down as CEO and handed that role over to cofounder Chris 58 | Wanstrath so I could focus on future-facing R&D projects with small teams. This 59 | kind of rapid, team-based innovation is what I live for. During my time away 60 | from GitHub I started experimenting with Go, OpenGL, and Unity with an eye 61 | towards the software side of immersive computing. It felt really good to get 62 | back into a code editor and challenge the deeply logical and analytical part of 63 | my brain. I've enjoyed the challenges of learning how to lead a company with 64 | hundreds of people, but it's very hard for me to deny the allure of coding a 65 | system that could once again change the course of history. 66 | 67 | I'm telling you this because I think stealth mode is bullshit and if you feel 68 | the same way I do about immersive computing then I want to talk with you about 69 | it. For the next few months I'm going to be living in Manhattan. My wife, 70 | Theresa, is currently participating in Techstars NYC as their very first 71 | nonprofit. Her startup, [The Omakase Charity](https://omakasecharity.org/), 72 | helps donors learn about and support nonprofits that are changing the world with 73 | technology. She's one of the strongest and most thoughtful women I know, and I'm 74 | hoping to help her succeed with her mission while I'm here. 75 | 76 | Thank you to everyone that reached out to me over the last month, including the 77 | generous team at Andreessen Horowitz. Your support has made a huge difference 78 | and I'm truly excited for what's next. 79 | -------------------------------------------------------------------------------- /test_projects/mojombo/_posts/2015-06-19-replicated.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Replicated - An Easier Path from SaaS to Enterprise 4 | --- 5 | 6 | {{ page.title }} 7 | ================ 8 | 9 |

19 Jun 2015 - San Francisco

10 | 11 | Over the last year I've had a chance to learn a lot more about early stage 12 | funding and made angel investments in a handful of startups. So far I've 13 | restricted my involvement to companies with ideas in which I have significant 14 | domain knowledge. I also insist on founders with relentless product focus, a 15 | fierce desire to help their customers be more awesome, and excellent 16 | communication skills. I recently met just such a company, with just such 17 | founders, tackling a problem that has personally caused me much pain. 18 | 19 | The company is [Replicated](http://replicated.com), and founders Grant Miller 20 | and Marc Campbell are making it easier to roll out an on-prem Enterprise 21 | offering based on an existing cloud-based SaaS product. 22 | 23 | At GitHub, we burned through **a lot** of developer cycles building our own 24 | installer (several times), securing the installation environment, coding an 25 | automated licensing management system, integrating single sign-on services 26 | (LDAP, Active Directory, CAS, etc, etc), building out a searchable audit system, 27 | supporting customer-reviewable support bundles (logs and other diagnostic 28 | output), allowing numerous backup strategies, and countless other 29 | Enterprise-specific features that were killing our Enterprise deals. All of this 30 | on top of hiring and building out the necessary sales, support, and accounting 31 | teams to create a smooth Enterprise experience for our customers. 32 | 33 | Replicated provides common Enterprise functionality (much of what I mentioned 34 | above, and all of it eventually) that you can wrap around your SaaS product, 35 | resulting in a first-class on-prem product in a fraction of the time. Beyond 36 | just technology, Replicated will help you understand your Enterprise customers 37 | through documentation on best practices and insight into the requirements and 38 | reasons that large companies desire the features they do. Until you can 39 | empathise with your customer (which is very hard to do as a fast-moving SaaS 40 | startup), you'll never build the best product possible. 41 | 42 | Getting into the Enterprise market will always be hard. But by reducing the 43 | technology burden, Replicated plans to erase much of the pain so you can focus 44 | on the other human-centric tasks. Not only am I an investor in Replicated, I 45 | believe in their mission and their founders so much that I've joined as an 46 | advisor. I understand what the uphill slog of the SaaS to Enterprise climb feels 47 | like, and I'm going to do my best to ensure you don't have to suffer it as much 48 | as I did. 49 | 50 | I'm also pleased to announce that Travis CI is now shipping their Enterprise 51 | product using Replicated. To see what the installation process is like, [watch 52 | Grant install Travis CI 53 | Enterprise](https://www.youtube.com/watch?v=ViN-qkcovL0&feature=youtu.be) on a 54 | fresh server in about seven minutes. For a deeper dive, Travis CI has also 55 | published a blog post covering some of their process in [getting their 56 | Enterprise installer ready using 57 | Replicated](http://blog.travis-ci.com/2015-06-19-how-we-improved-travis-ci-installation/). 58 | 59 | In the coming weeks, you'll start to see other well-known startups launching (or 60 | re-launching) Enterprise versions of their SaaS software on top of Replicated. 61 | If you're looking to do the same, and want to save yourself a lot of heartache, 62 | email [contact@replicated.com](mailto:contact@replicated.com), and start 63 | focusing on what matters the most: your unique and kickass product. 64 | -------------------------------------------------------------------------------- /test_projects/mojombo/_posts/2016-11-10-snyk.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Snyk - Automatically Scan and Fix Ruby and Nodejs Vulnerabilities 4 | --- 5 | 6 | {{ page.title }} 7 | ================ 8 | 9 |

10 Nov 2016 - San Francisco

10 | 11 | This is a story about a company called 12 | [Snyk](https://snyk.io/blog/welcome-ruby-users/) (pronounced "sneak"), their 13 | founder Guy Podjarny, my decision to become one of their advisors, and how they 14 | are going to help save you from malevolent agents trying to steal your digital 15 | stuff. 16 | 17 | If you're anything like me, you're simultaneously terrified and in awe of the 18 | increasing commonality of large corporate security breaches. Even big names like 19 | Ebay, Home Depot, Anthem, JP Morgan Chase, Target, LinkedIn, Dropbox, and Yahoo 20 | are falling victim to sophisticated attacks. If you spend even a few minutes 21 | looking into it, you'll be shocked at how frequently these breaches are 22 | happening now. The fine folks at Information is Beautiful have an excellent 23 | interactive visualization of the [World's Biggest Data 24 | Breaches](http://www.informationisbeautiful.net/visualizations/worlds-biggest-data-breaches-hacks/) 25 | over the last twelve years, in case you want to read all the gory details and 26 | never get a restful night of sleep ever again: 27 | 28 | 29 | 30 | 31 | 32 | I've used a fair number of emotionally charged words above that might be 33 | triggering your FUD detectors right about now. But be advised: it's not paranoia 34 | when they really are out to get you. If recent, extremely high profile (and 35 | subsequently weaponized) breaches like those of the Clinton Campaign and the DNC 36 | aren't enough to make you want to air gap your entire life, then I envy your 37 | steely-eyed mettle and implore you to teach me your meditation techniques. 38 | 39 | The fact is, security is hard. And it's getting harder every day. To win, you 40 | have to get it right every single time. To lose (and lose big), you only have to 41 | screw it up once. 42 | 43 | During my years at GitHub, I spent a lot of time assembling a dedicated security 44 | team, managing security audits and penetration tests, and working to establish a 45 | culture of security awareness amongst our development team. All of this is 46 | challenging and expensive, especially for a young company. Even worse, it's the 47 | kind of investment that's totally invisible when it's working, making it hard to 48 | sustain until that crucial and terrible moment you end up on the front page of 49 | Hacker News as the latest victim. 50 | 51 | A year ago I was contemplating this, especially the difficult proposition of 52 | having developers, furious at work on new features, constantly maintain 53 | awareness of security vulnerabilities they might be inadvertently weaving into 54 | the product. Web application developers are generally not security experts, and 55 | though I would love to live in a world where that wasn't true, it's just not a 56 | realistic expectation. Meanwhile, modern development means an increasing 57 | reliance on 3rd party code. Even a small Rails app will probably have 300 or 58 | more gem dependencies after a few months of development. It's even more in the 59 | nodejs world. This level of modularization and code reuse, driven by the 60 | explosion of high quality open source over the last decade, is amazing and I 61 | absolutely love it, but it comes at a security expense. 62 | 63 | Open source projects are not known for their excellent security records. 64 | Vulnerabilities like [Heartbleed](http://heartbleed.com/) and 65 | [Shellshock](https://blog.cloudflare.com/inside-shellshock/) painfully 66 | demonstrate the idea that "given enough eyeballs, all bugs are shallow" is 67 | completely false. In fact, due to a flaw in YAML, Rails had a [pretty extreme 68 | remote code execution 69 | vulnerability](http://blog.codeclimate.com/blog/2013/01/10/rails-remote-code-execution-vulnerability-explained/) 70 | for years. If you were running any version of Rails prior to the fix, you were 71 | vulnerable. This stuff is real, and as responsible developers, we need to be 72 | more proactive about it. 73 | 74 | Luckily, at the time I was pondering these matters, I ran into Guy Podjarny. As 75 | a former cofounder of Blaze.io and then CTO of Web Experience at Akamai (which 76 | acquired Blaze.io), Guy intimately understands the impact of security on today's 77 | web developers. He was working on an automated tool to scan and fix security 78 | vulnerabilities in 3rd party dependencies. I was intrigued. They already had a 79 | way to scan nodejs projects and look for known security vulnerabilities in the 80 | dependency tree and automatically upgrade or patch affected libraries. I thought 81 | this was pretty cool, but it was his vision for what automated security tooling 82 | could be that sold me on him and his company. I can't talk much about that 83 | now, but just know that what Snyk is today is just the tip of what will 84 | become an intelligent and proactive bodyguard for your entire codebase. 85 | 86 | A few months ago, Snyk released GitHub integration to make it fantastically 87 | simple to hook up your repos to Snyk and, my favorite feature: the ability to 88 | monitor your repo for future vulnerabilities and then **automatically submit a 89 | pull request** with the suggested package upgrade or hotfix patch (nodejs only for 90 | now). 91 | 92 | Today, [Snyk announced support for 93 | Ruby](https://snyk.io/blog/welcome-ruby-users/). Take a look at that blog post, 94 | it does an awesome job of explaining how simple it is to set up and what the 95 | generated pull requests look like. It's totally free for open source projects, 96 | and extremely cheap insurance for your important projects. 97 | 98 | Make no mistake, 3rd party code is a clear and present danger to your business. 99 | If you don't know if you're vulnerable, then you must assume that you are and 100 | take steps to protect yourself. Snyk makes it easy. 101 | -------------------------------------------------------------------------------- /test_projects/mojombo/atom.xml: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | 5 | 6 | Tom Preston-Werner 7 | 8 | 9 | {{ site.time | date_to_xmlschema }} 10 | http://tom.preston-werner.com/ 11 | 12 | Tom Preston-Werner 13 | tom@mojombo.com 14 | 15 | 16 | {% for post in site.posts %} 17 | 18 | {{ post.title }} 19 | 20 | {{ post.date | date_to_xmlschema }} 21 | http://tom.preston-werner.com{{ post.id }} 22 | {{ post.content | xml_escape }} 23 | 24 | {% endfor %} 25 | 26 | 27 | -------------------------------------------------------------------------------- /test_projects/mojombo/css/screen.css: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* 3 | /* Common 4 | /* 5 | /*****************************************************************************/ 6 | 7 | /* Global Reset */ 8 | 9 | * { 10 | margin: 0; 11 | padding: 0; 12 | } 13 | 14 | html, body { 15 | height: 100%; 16 | } 17 | 18 | body { 19 | background-color: white; 20 | font: 13.34px helvetica, arial, clean, sans-serif; 21 | *font-size: small; 22 | text-align: center; 23 | } 24 | 25 | h1, h2, h3, h4, h5, h6 { 26 | font-size: 100%; 27 | } 28 | 29 | h1 { 30 | margin-bottom: 1em; 31 | } 32 | 33 | p { 34 | margin: 1em 0; 35 | } 36 | 37 | a { 38 | color: #00a; 39 | } 40 | 41 | a:hover { 42 | color: black; 43 | } 44 | 45 | a:visited { 46 | color: #a0a; 47 | } 48 | 49 | table { 50 | font-size: inherit; 51 | font: 100%; 52 | } 53 | 54 | /*****************************************************************************/ 55 | /* 56 | /* Home 57 | /* 58 | /*****************************************************************************/ 59 | 60 | ul.posts { 61 | list-style-type: none; 62 | margin-bottom: 2em; 63 | } 64 | 65 | ul.posts li { 66 | line-height: 1.75em; 67 | } 68 | 69 | ul.posts span { 70 | color: #aaa; 71 | font-family: Monaco, "Courier New", monospace; 72 | font-size: 80%; 73 | } 74 | 75 | /*****************************************************************************/ 76 | /* 77 | /* Site 78 | /* 79 | /*****************************************************************************/ 80 | 81 | .site { 82 | font-size: 110%; 83 | text-align: justify; 84 | width: 42em; 85 | margin: 3em auto 2em auto; 86 | line-height: 1.5em; 87 | } 88 | 89 | .title { 90 | color: #a00; 91 | font-weight: bold; 92 | margin-bottom: 2em; 93 | } 94 | 95 | .site .title a { 96 | color: #a00; 97 | text-decoration: none; 98 | } 99 | 100 | .site .title a:hover { 101 | color: black; 102 | } 103 | 104 | .site .title a.extra { 105 | color: #aaa; 106 | text-decoration: none; 107 | margin-left: 1em; 108 | } 109 | 110 | .site .title a.extra:hover { 111 | color: black; 112 | } 113 | 114 | .site .meta { 115 | color: #aaa; 116 | } 117 | 118 | .site .footer { 119 | font-size: 80%; 120 | color: #666; 121 | border-top: 4px solid #eee; 122 | margin-top: 2em; 123 | overflow: hidden; 124 | } 125 | 126 | .site .footer .contact { 127 | float: left; 128 | margin-right: 3em; 129 | } 130 | 131 | .site .footer .contact a { 132 | color: #8085C1; 133 | } 134 | 135 | .site .footer .rss { 136 | margin-top: 1.1em; 137 | margin-right: -.2em; 138 | float: right; 139 | } 140 | 141 | .site .footer .rss img { 142 | border: 0; 143 | } 144 | 145 | /*****************************************************************************/ 146 | /* 147 | /* Posts 148 | /* 149 | /*****************************************************************************/ 150 | 151 | #post { 152 | 153 | } 154 | 155 | /* standard */ 156 | 157 | #post pre { 158 | border: 1px solid #ddd; 159 | background-color: #eef; 160 | padding: 0 .4em; 161 | } 162 | 163 | #post ul, 164 | #post ol { 165 | margin-left: 1.35em; 166 | } 167 | 168 | #post code { 169 | border: 1px solid #ddd; 170 | background-color: #eef; 171 | font-size: 85%; 172 | padding: 0 .2em; 173 | } 174 | 175 | #post pre code { 176 | border: none; 177 | } 178 | 179 | #post img { 180 | max-width: 42em; 181 | padding: 1em 0; 182 | } 183 | 184 | /* terminal */ 185 | 186 | #post pre.terminal { 187 | border: 1px solid black; 188 | background-color: #333; 189 | color: white; 190 | } 191 | 192 | #post pre.terminal code { 193 | background-color: #333; 194 | } 195 | 196 | #related { 197 | margin-top: 2em; 198 | } 199 | 200 | #related h2 { 201 | margin-bottom: 1em; 202 | } 203 | -------------------------------------------------------------------------------- /test_projects/mojombo/css/syntax.css: -------------------------------------------------------------------------------- 1 | .highlight { background: #ffffff; } 2 | .highlight .c { color: #999988; font-style: italic } /* Comment */ 3 | .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ 4 | .highlight .k { font-weight: bold } /* Keyword */ 5 | .highlight .o { font-weight: bold } /* Operator */ 6 | .highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ 7 | .highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ 8 | .highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ 9 | .highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ 10 | .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ 11 | .highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ 12 | .highlight .ge { font-style: italic } /* Generic.Emph */ 13 | .highlight .gr { color: #aa0000 } /* Generic.Error */ 14 | .highlight .gh { color: #999999 } /* Generic.Heading */ 15 | .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ 16 | .highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ 17 | .highlight .go { color: #888888 } /* Generic.Output */ 18 | .highlight .gp { color: #555555 } /* Generic.Prompt */ 19 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 20 | .highlight .gu { color: #aaaaaa } /* Generic.Subheading */ 21 | .highlight .gt { color: #aa0000 } /* Generic.Traceback */ 22 | .highlight .kc { font-weight: bold } /* Keyword.Constant */ 23 | .highlight .kd { font-weight: bold } /* Keyword.Declaration */ 24 | .highlight .kp { font-weight: bold } /* Keyword.Pseudo */ 25 | .highlight .kr { font-weight: bold } /* Keyword.Reserved */ 26 | .highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ 27 | .highlight .m { color: #009999 } /* Literal.Number */ 28 | .highlight .s { color: #d14 } /* Literal.String */ 29 | .highlight .na { color: #008080 } /* Name.Attribute */ 30 | .highlight .nb { color: #0086B3 } /* Name.Builtin */ 31 | .highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ 32 | .highlight .no { color: #008080 } /* Name.Constant */ 33 | .highlight .ni { color: #800080 } /* Name.Entity */ 34 | .highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ 35 | .highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ 36 | .highlight .nn { color: #555555 } /* Name.Namespace */ 37 | .highlight .nt { color: #000080 } /* Name.Tag */ 38 | .highlight .nv { color: #008080 } /* Name.Variable */ 39 | .highlight .ow { font-weight: bold } /* Operator.Word */ 40 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 41 | .highlight .mf { color: #009999 } /* Literal.Number.Float */ 42 | .highlight .mh { color: #009999 } /* Literal.Number.Hex */ 43 | .highlight .mi { color: #009999 } /* Literal.Number.Integer */ 44 | .highlight .mo { color: #009999 } /* Literal.Number.Oct */ 45 | .highlight .sb { color: #d14 } /* Literal.String.Backtick */ 46 | .highlight .sc { color: #d14 } /* Literal.String.Char */ 47 | .highlight .sd { color: #d14 } /* Literal.String.Doc */ 48 | .highlight .s2 { color: #d14 } /* Literal.String.Double */ 49 | .highlight .se { color: #d14 } /* Literal.String.Escape */ 50 | .highlight .sh { color: #d14 } /* Literal.String.Heredoc */ 51 | .highlight .si { color: #d14 } /* Literal.String.Interpol */ 52 | .highlight .sx { color: #d14 } /* Literal.String.Other */ 53 | .highlight .sr { color: #009926 } /* Literal.String.Regex */ 54 | .highlight .s1 { color: #d14 } /* Literal.String.Single */ 55 | .highlight .ss { color: #990073 } /* Literal.String.Symbol */ 56 | .highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ 57 | .highlight .vc { color: #008080 } /* Name.Variable.Class */ 58 | .highlight .vg { color: #008080 } /* Name.Variable.Global */ 59 | .highlight .vi { color: #008080 } /* Name.Variable.Instance */ 60 | .highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ 61 | -------------------------------------------------------------------------------- /test_projects/mojombo/images/posts/2016-11-10/breaches.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/mojombo/images/posts/2016-11-10/breaches.png -------------------------------------------------------------------------------- /test_projects/mojombo/images/rss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/mojombo/images/rss.png -------------------------------------------------------------------------------- /test_projects/mojombo/pgp.txt: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | Version: GnuPG v1.4.11 (Darwin) 3 | 4 | mQENBE9e0pIBCADXib13PNjCbKH0dbCGMRDNDtg1Fp75t/jr7lqJE8C9B5XlrAXb 5 | O1uScvzRUt+myNyEhk21lA8KmTR0f1up84frxdTV7H4evePWbYbKigVu5zKKAvnG 6 | hGPnxtAslxvB/0fV1s+1IFpIG2VADHTaJ3ESyXR21S3tx9Uca3WQ9H2Jq32ur0Ox 7 | eCvRD1Tu8/YXLtOi3oyZZssqy7L9NpYOCZG7mQunds7LGSfz8ucWLlgUunV3seHB 8 | R0CUSYccphRAfrtr4lPbb9RXrXNVKtcoHbiDnSnzayjcghvjQuPDyca09fJDO4nk 9 | NlUlJmc0Pgcc4eFcCAnuVIR8RamGZ/+0gZDBABEBAAG0Q1RvbSBQcmVzdG9uLVdl 10 | cm5lciAoQ29mb3VuZGVyICYgQ1RPLCBHaXRIdWIsIEluYy4pIDx0b21AZ2l0aHVi 11 | LmNvbT6JATgEEwECACIFAk9e0pICGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheA 12 | AAoJEKphtGN5qvflqU4H/jAxh8YMwbSWgnilFbhYPoYL+jPyY74pA/fNSYcTy7qH 13 | 5vVNfImuQ94oyQZosq85J1jXT1ln/liQzdbdKTt36HQDGTSyRJD2FfVUmFMYtC8B 14 | IR+RpaCqNdboZPxZcmuFSERqjv1xEyc+9tAlsMg+T8CwpDUft2OgS46SyMcVZ0dh 15 | G56zrZAR/x/ZapxrIfAzRj6CSunJEa82BCvgkzI8X8BsMdiEFT5A02wrFCA7qbDv 16 | +197SiV0Ishv2m5WeU/qGIUsps3TLgeyZnyiqYKQZcIFBhZ0PR+WQRbw2Ct7Yefz 17 | b8wcT6if8mZGZrGOBJorCZe50AUKHkaS+JoPXzGexIC5AQ0ET17SkgEIALvtGjPp 18 | Vx87cC1nkcd3iRpv+/02wb5u/KiQqa0qmW3u3wcKTVlk58ZLhNxDqH/l+ClzhKpb 19 | nb6c3hCkLF9te1royibkJGlb83YAJLDJM3a389Sd1vfgFNk7POdSgZ72EPzGiUnn 20 | o8cZRXPhThbuL0D6ZA3oUfW23VVt+3oh3ieF9cnhaPL/d+te9lfvypt6BERdzoYp 21 | JF4bWl0MN0GALW5lH0AkoEYBM7kLyWqEqB1wie4xEsh9cRbx5e5KCJFD6JyT9g80 22 | HUDJyJV9D6SEIU2lyqBnVSuRE16jmAEZuUqhldpZocNtmrF0JF5evciYPnJrULD2 23 | YTepopzPXCGAqdUAEQEAAYkBHwQYAQIACQUCT17SkgIbDAAKCRCqYbRjear35SKk 24 | CACpmJXhORU12Sjmyfpgs4z+t1kGbuaRvJl18llZ3T2mzxs1mDV1uTZ7eVc+af+e 25 | HkhEaIVO35By6sg4Y2xV8cW+J+YKUpGTKoUVqb0tLn2R/xJx1hbQUle3rOlfOCO3 26 | dHclvXzYAsRGwMpOj8idu8Q8yUH2FncRU7iCxmkgxtp6/tPo06z9ZYsAM1DyELcj 27 | Y2jJ57A8urwkbRCBXGJnAYCM70MPXPKuxheL3mDPHHgE5aUWc4BQH9Oz4PWeuVGB 28 | ZGjzDtHLzltuWZQXURNk3nklDG84AZ8SLMxMlNvYqfwVqhLld7rQkncjH8/kkUxJ 29 | jrpwB041z2lIc22q/ZDsctSM 30 | =vrTm 31 | -----END PGP PUBLIC KEY BLOCK----- 32 | -------------------------------------------------------------------------------- /test_projects/mojombo/random/canvas_rotated_textfill.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Canvas Rotated textFill 5 | 6 | 7 | 8 | 9 | 53 | 54 | -------------------------------------------------------------------------------- /test_projects/octicons/README.md: -------------------------------------------------------------------------------- 1 | # Readme Test 2 | 3 | {% octicon alert height:32 class:"right left" aria-label:hi %} 4 | 5 | 6 | -------------------------------------------------------------------------------- /test_projects/octicons/_config.yml: -------------------------------------------------------------------------------- 1 | plugins: 2 | - jekyll-octicons 3 | -------------------------------------------------------------------------------- /test_projects/octicons/_expected/README.md: -------------------------------------------------------------------------------- 1 | # Readme Test 2 | 3 | {% octicon alert height:32 class:"right left" aria-label:hi %} 4 | 5 | 6 | -------------------------------------------------------------------------------- /test_projects/octicons/_expected/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Readme Test | jekyll-build-pages 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
40 | 41 |

jekyll-build-pages

42 | 43 | 44 |

Readme Test

45 | 46 | 47 | 48 | 49 | 50 | 51 | 54 | 55 |
56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /test_projects/readme/README.md: -------------------------------------------------------------------------------- 1 | # Readme Test 2 | 3 | Uses jekyll-readme-index plugin by default. 4 | 5 | Here's a jemoji :+1: 6 | -------------------------------------------------------------------------------- /test_projects/readme/_config.yml: -------------------------------------------------------------------------------- 1 | plugins: 2 | - jemoji 3 | -------------------------------------------------------------------------------- /test_projects/readme/_expected/README.md: -------------------------------------------------------------------------------- 1 | # Readme Test 2 | 3 | Uses jekyll-readme-index plugin by default. 4 | 5 | Here's a jemoji :+1: 6 | -------------------------------------------------------------------------------- /test_projects/readme/_expected/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Readme Test | jekyll-build-pages 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
40 | 41 |

jekyll-build-pages

42 | 43 | 44 |

Readme Test

45 | 46 |

Uses jekyll-readme-index plugin by default.

47 | 48 |

Here’s a jemoji :+1:

49 | 50 | 51 | 52 | 55 | 56 |
57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /test_projects/simple/_config.yaml: -------------------------------------------------------------------------------- 1 | title: "Jekyll Actions Demo" 2 | -------------------------------------------------------------------------------- /test_projects/simple/_expected/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Jekyll Actions Demo | A simple GitHub Action for producing Jekyll build artifacts compatible with GitHub Pages. 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
40 | 41 |

Jekyll Actions Demo

42 | 43 | 44 |

Hello Welcome to My Home Page

45 | 46 |
    47 |
  • Original date - 2020-04-13T10:20:00Z
  • 48 |
  • With timeago filter - 2020-04-13T10:20:00Z
  • 49 |
50 | 51 | 52 | 53 | 56 | 57 |
58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /test_projects/simple/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | Hello Welcome to My Home Page 5 | 6 | {% assign date = '2020-04-13T10:20:00Z' %} 7 | 8 | - Original date - {{ date }} 9 | - With timeago filter - {{ date | timeago }} 10 | -------------------------------------------------------------------------------- /test_projects/themes/_config.yml: -------------------------------------------------------------------------------- 1 | title: "themes" 2 | theme: jekyll-theme-minimal 3 | -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/css/style.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:'Noto Sans';font-weight:400;font-style:normal;src:url("../fonts/Noto-Sans-regular/Noto-Sans-regular.eot");src:url("../fonts/Noto-Sans-regular/Noto-Sans-regular.eot?#iefix") format("embedded-opentype"),local("Noto Sans"),local("Noto-Sans-regular"),url("../fonts/Noto-Sans-regular/Noto-Sans-regular.woff2") format("woff2"),url("../fonts/Noto-Sans-regular/Noto-Sans-regular.woff") format("woff"),url("../fonts/Noto-Sans-regular/Noto-Sans-regular.ttf") format("truetype"),url("../fonts/Noto-Sans-regular/Noto-Sans-regular.svg#NotoSans") format("svg")}@font-face{font-family:'Noto Sans';font-weight:700;font-style:normal;src:url("../fonts/Noto-Sans-700/Noto-Sans-700.eot");src:url("../fonts/Noto-Sans-700/Noto-Sans-700.eot?#iefix") format("embedded-opentype"),local("Noto Sans Bold"),local("Noto-Sans-700"),url("../fonts/Noto-Sans-700/Noto-Sans-700.woff2") format("woff2"),url("../fonts/Noto-Sans-700/Noto-Sans-700.woff") format("woff"),url("../fonts/Noto-Sans-700/Noto-Sans-700.ttf") format("truetype"),url("../fonts/Noto-Sans-700/Noto-Sans-700.svg#NotoSans") format("svg")}@font-face{font-family:'Noto Sans';font-weight:400;font-style:italic;src:url("../fonts/Noto-Sans-italic/Noto-Sans-italic.eot");src:url("../fonts/Noto-Sans-italic/Noto-Sans-italic.eot?#iefix") format("embedded-opentype"),local("Noto Sans Italic"),local("Noto-Sans-italic"),url("../fonts/Noto-Sans-italic/Noto-Sans-italic.woff2") format("woff2"),url("../fonts/Noto-Sans-italic/Noto-Sans-italic.woff") format("woff"),url("../fonts/Noto-Sans-italic/Noto-Sans-italic.ttf") format("truetype"),url("../fonts/Noto-Sans-italic/Noto-Sans-italic.svg#NotoSans") format("svg")}@font-face{font-family:'Noto Sans';font-weight:700;font-style:italic;src:url("../fonts/Noto-Sans-700italic/Noto-Sans-700italic.eot");src:url("../fonts/Noto-Sans-700italic/Noto-Sans-700italic.eot?#iefix") format("embedded-opentype"),local("Noto Sans Bold Italic"),local("Noto-Sans-700italic"),url("../fonts/Noto-Sans-700italic/Noto-Sans-700italic.woff2") format("woff2"),url("../fonts/Noto-Sans-700italic/Noto-Sans-700italic.woff") format("woff"),url("../fonts/Noto-Sans-700italic/Noto-Sans-700italic.ttf") format("truetype"),url("../fonts/Noto-Sans-700italic/Noto-Sans-700italic.svg#NotoSans") format("svg")}.highlight table td{padding:5px}.highlight table pre{margin:0}.highlight .cm{color:#999988;font-style:italic}.highlight .cp{color:#999999;font-weight:bold}.highlight .c1{color:#999988;font-style:italic}.highlight .cs{color:#999999;font-weight:bold;font-style:italic}.highlight .c,.highlight .cd{color:#999988;font-style:italic}.highlight .err{color:#a61717;background-color:#e3d2d2}.highlight .gd{color:#000000;background-color:#ffdddd}.highlight .ge{color:#000000;font-style:italic}.highlight .gr{color:#aa0000}.highlight .gh{color:#999999}.highlight .gi{color:#000000;background-color:#ddffdd}.highlight .go{color:#888888}.highlight .gp{color:#555555}.highlight .gs{font-weight:bold}.highlight .gu{color:#aaaaaa}.highlight .gt{color:#aa0000}.highlight .kc{color:#000000;font-weight:bold}.highlight .kd{color:#000000;font-weight:bold}.highlight .kn{color:#000000;font-weight:bold}.highlight .kp{color:#000000;font-weight:bold}.highlight .kr{color:#000000;font-weight:bold}.highlight .kt{color:#445588;font-weight:bold}.highlight .k,.highlight .kv{color:#000000;font-weight:bold}.highlight .mf{color:#009999}.highlight .mh{color:#009999}.highlight .il{color:#009999}.highlight .mi{color:#009999}.highlight .mo{color:#009999}.highlight .m,.highlight .mb,.highlight .mx{color:#009999}.highlight .sb{color:#d14}.highlight .sc{color:#d14}.highlight .sd{color:#d14}.highlight .s2{color:#d14}.highlight .se{color:#d14}.highlight .sh{color:#d14}.highlight .si{color:#d14}.highlight .sx{color:#d14}.highlight .sr{color:#009926}.highlight .s1{color:#d14}.highlight .ss{color:#990073}.highlight .s{color:#d14}.highlight .na{color:#008080}.highlight .bp{color:#999999}.highlight .nb{color:#0086B3}.highlight .nc{color:#445588;font-weight:bold}.highlight .no{color:#008080}.highlight .nd{color:#3c5d5d;font-weight:bold}.highlight .ni{color:#800080}.highlight .ne{color:#990000;font-weight:bold}.highlight .nf{color:#990000;font-weight:bold}.highlight .nl{color:#990000;font-weight:bold}.highlight .nn{color:#555555}.highlight .nt{color:#000080}.highlight .vc{color:#008080}.highlight .vg{color:#008080}.highlight .vi{color:#008080}.highlight .nv{color:#008080}.highlight .ow{color:#000000;font-weight:bold}.highlight .o{color:#000000;font-weight:bold}.highlight .w{color:#bbbbbb}.highlight{background-color:#f8f8f8}body{background-color:#fff;padding:50px;font:14px/1.5 "Noto Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;color:#727272;font-weight:400}h1,h2,h3,h4,h5,h6{color:#222;margin:0 0 20px}p,ul,ol,table,pre,dl{margin:0 0 20px}h1,h2,h3{line-height:1.1}h1{font-size:28px}h2{color:#393939}h3,h4,h5,h6{color:#494949}a{color:#267CB9;text-decoration:none}a:hover,a:focus{color:#069;font-weight:bold}a small{font-size:11px;color:#777;margin-top:-0.3em;display:block}a:hover small{color:#777}.wrapper{width:860px;margin:0 auto}blockquote{border-left:1px solid #e5e5e5;margin:0;padding:0 0 0 20px;font-style:italic}code,pre{font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal, Consolas, Liberation Mono, DejaVu Sans Mono, Courier New, monospace;color:#333}pre{padding:8px 15px;background:#f8f8f8;border-radius:5px;border:1px solid #e5e5e5;overflow-x:auto}table{width:100%;border-collapse:collapse}th,td{text-align:left;padding:5px 10px;border-bottom:1px solid #e5e5e5}dt{color:#444;font-weight:700}th{color:#444}img{max-width:100%}kbd{background-color:#fafbfc;border:1px solid #c6cbd1;border-bottom-color:#959da5;border-radius:3px;box-shadow:inset 0 -1px 0 #959da5;color:#444d56;display:inline-block;font-size:11px;line-height:10px;padding:3px 5px;vertical-align:middle}header{width:270px;float:left;position:fixed;-webkit-font-smoothing:subpixel-antialiased}ul.downloads{list-style:none;height:40px;padding:0;background:#f4f4f4;border-radius:5px;border:1px solid #e0e0e0;width:270px}.downloads li{width:89px;float:left;border-right:1px solid #e0e0e0;height:40px}.downloads li:first-child a{border-radius:5px 0 0 5px}.downloads li:last-child a{border-radius:0 5px 5px 0}.downloads a{line-height:1;font-size:11px;color:#676767;display:block;text-align:center;padding-top:6px;height:34px}.downloads a:hover,.downloads a:focus{color:#675C5C;font-weight:bold}.downloads ul a:active{background-color:#f0f0f0}strong{color:#222;font-weight:700}.downloads li+li+li{border-right:none;width:89px}.downloads a strong{font-size:14px;display:block;color:#222}section{width:500px;float:right;padding-bottom:50px}small{font-size:11px}hr{border:0;background:#e5e5e5;height:1px;margin:0 0 20px}footer{width:270px;float:left;position:fixed;bottom:50px;-webkit-font-smoothing:subpixel-antialiased}@media print, screen and (max-width: 960px){div.wrapper{width:auto;margin:0}header,section,footer{float:none;position:static;width:auto}header{padding-right:320px}section{border:1px solid #e5e5e5;border-width:1px 0;padding:20px 0;margin:0 0 20px}header a small{display:inline}header ul{position:absolute;right:50px;top:52px}}@media print, screen and (max-width: 720px){body{word-wrap:break-word}header{padding:0}header ul,header p.view{position:static}pre,code{word-wrap:normal}}@media print, screen and (max-width: 480px){body{padding:15px}.downloads{width:99%}.downloads li,.downloads li+li+li{width:33%}}@media print{body{padding:0.4in;font-size:12pt;color:#444}} 2 | -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/fonts/Noto-Sans-700/Noto-Sans-700.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/fonts/Noto-Sans-700/Noto-Sans-700.eot -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/fonts/Noto-Sans-700/Noto-Sans-700.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/fonts/Noto-Sans-700/Noto-Sans-700.ttf -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/fonts/Noto-Sans-700/Noto-Sans-700.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/fonts/Noto-Sans-700/Noto-Sans-700.woff -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/fonts/Noto-Sans-700/Noto-Sans-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/fonts/Noto-Sans-700/Noto-Sans-700.woff2 -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/fonts/Noto-Sans-700italic/Noto-Sans-700italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/fonts/Noto-Sans-700italic/Noto-Sans-700italic.eot -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/fonts/Noto-Sans-700italic/Noto-Sans-700italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/fonts/Noto-Sans-700italic/Noto-Sans-700italic.ttf -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/fonts/Noto-Sans-700italic/Noto-Sans-700italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/fonts/Noto-Sans-700italic/Noto-Sans-700italic.woff -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/fonts/Noto-Sans-700italic/Noto-Sans-700italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/fonts/Noto-Sans-700italic/Noto-Sans-700italic.woff2 -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/fonts/Noto-Sans-italic/Noto-Sans-italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/fonts/Noto-Sans-italic/Noto-Sans-italic.eot -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/fonts/Noto-Sans-italic/Noto-Sans-italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/fonts/Noto-Sans-italic/Noto-Sans-italic.ttf -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/fonts/Noto-Sans-italic/Noto-Sans-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/fonts/Noto-Sans-italic/Noto-Sans-italic.woff -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/fonts/Noto-Sans-italic/Noto-Sans-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/fonts/Noto-Sans-italic/Noto-Sans-italic.woff2 -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/fonts/Noto-Sans-regular/Noto-Sans-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/fonts/Noto-Sans-regular/Noto-Sans-regular.eot -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/fonts/Noto-Sans-regular/Noto-Sans-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/fonts/Noto-Sans-regular/Noto-Sans-regular.ttf -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/fonts/Noto-Sans-regular/Noto-Sans-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/fonts/Noto-Sans-regular/Noto-Sans-regular.woff -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/fonts/Noto-Sans-regular/Noto-Sans-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/fonts/Noto-Sans-regular/Noto-Sans-regular.woff2 -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/actions/jekyll-build-pages/c2d3f388e1c98cd181c6371f87c58e0a3313e693/test_projects/themes/_expected/assets/img/logo.png -------------------------------------------------------------------------------- /test_projects/themes/_expected/assets/js/scale.fix.js: -------------------------------------------------------------------------------- 1 | (function(document) { 2 | var metas = document.getElementsByTagName('meta'), 3 | changeViewportContent = function(content) { 4 | for (var i = 0; i < metas.length; i++) { 5 | if (metas[i].name == "viewport") { 6 | metas[i].content = content; 7 | } 8 | } 9 | }, 10 | initialize = function() { 11 | changeViewportContent("width=device-width, minimum-scale=1.0, maximum-scale=1.0"); 12 | }, 13 | gestureStart = function() { 14 | changeViewportContent("width=device-width, minimum-scale=0.25, maximum-scale=1.6"); 15 | }, 16 | gestureEnd = function() { 17 | initialize(); 18 | }; 19 | 20 | 21 | if (navigator.userAgent.match(/iPhone/i)) { 22 | initialize(); 23 | 24 | document.addEventListener("touchstart", gestureStart, false); 25 | document.addEventListener("touchend", gestureEnd, false); 26 | } 27 | })(document); 28 | -------------------------------------------------------------------------------- /test_projects/themes/_expected/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | themes | A simple GitHub Action for producing Jekyll build artifacts compatible with GitHub Pages. 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 |
44 |

themes

45 | 46 | 47 | 48 |

A simple GitHub Action for producing Jekyll build artifacts compatible with GitHub Pages.

49 | 50 | 51 |

View the Project on GitHub actions/jekyll-build-pages

52 | 53 | 54 | 55 | 56 | 57 |
58 |
59 | 60 |

Theme: jekyll-theme-minimal

61 | 62 | 63 |
64 |
65 | 66 |

This project is maintained by actions

67 | 68 |

Hosted on GitHub Pages — Theme by orderedlist

69 |
70 |
71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /test_projects/themes/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | Theme: {{ site.theme }} 5 | --------------------------------------------------------------------------------