From 99b422f0cbf81a689635fd24142dde9ffff50b64 Mon Sep 17 00:00:00 2001 From: Nick Alteen Date: Fri, 15 Sep 2023 12:32:38 -0400 Subject: [PATCH] Expand README and CI --- .github/dependabot.yml | 17 ++ .github/workflows/ci.yml | 104 ++++++++++ .github/workflows/codeql-analysis.yml | 48 +++++ CODEOWNERS | 4 + README.md | 277 +++++++++++++++++++++++++- 5 files changed, 447 insertions(+), 3 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/codeql-analysis.yml create mode 100644 CODEOWNERS diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..70cb209 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,17 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + labels: + - dependabot + - actions + schedule: + interval: daily + + - package-ecosystem: docker + directory: / + labels: + - dependabot + - docker + schedule: + interval: daily diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..4fce9d1 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,104 @@ +name: Continuous Integration + +on: + pull_request: + branches: + - main + push: + branches: + - main + +jobs: + test-typescript: + name: TypeScript Tests + runs-on: ubuntu-latest + + steps: + - name: Checkout + id: checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + id: setup-node + uses: actions/setup-node@v3 + with: + node-version: 20 + cache: npm + + - name: Install Dependencies + id: npm-ci + run: npm ci + + - name: Check Format + id: npm-format-check + run: npm run format:check + + - name: Lint + id: npm-lint + run: npm run lint + + - name: Test + id: npm-ci-test + run: npm run ci-test + + test-docker: + name: Docker Tests + runs-on: ubuntu-latest + + # Run a local registry to push to + services: + registry: + image: registry:2 + ports: + - 5001:5000 + + env: + TEST_TAG: localhost:5001/actions/container-toolkit-action:latest + + steps: + - name: Checkout + id: checkout + uses: actions/checkout@v4 + + - name: Setup Docker BuildX + id: setup-buildx + uses: docker/setup-buildx-action@v3 + with: + install: true + driver-opts: network=host + + - name: Build the Container + id: build + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: ${{ env.TEST_TAG }} + + - name: Run the Container + id: run + env: + INPUT_MILLISECONDS: 2000 + run: | + docker run \ + --env INPUT_MILLISECONDS="${{ env.INPUT_MILLISECONDS }}" \ + --rm ${{ env.TEST_TAG }} + + test-action: + name: GitHub Actions Test + runs-on: ubuntu-latest + + steps: + - name: Checkout + id: checkout + uses: actions/checkout@v4 + + - name: Test Local Action + id: test-action + uses: ./ + with: + milliseconds: 2000 + + - name: Print Output + id: output + run: echo "${{ steps.test-action.outputs.time }}" diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..bcaf277 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,48 @@ +name: CodeQL + +on: + push: + branches: + - main + pull_request: + branches: + - main + schedule: + - cron: '31 7 * * 3' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + permissions: + actions: read + checks: write + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: + - TypeScript + + steps: + - name: Checkout + id: checkout + uses: actions/checkout@v4 + + - name: Initialize CodeQL + id: initialize + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + source-root: src + + - name: Autobuild + id: autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + id: analyze + uses: github/codeql-action/analyze@v2 diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..6ac23c1 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,4 @@ +# Repository CODEOWNERS + +* @actions/actions-runtime +* @ncalteen \ No newline at end of file diff --git a/README.md b/README.md index 1d52944..caa4911 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,276 @@ -# Container Action Template +# Create a Container Action with the GitHub Actions Toolkit -To get started, click the `Use this template` button on this repository [which will create a new repository based on this template](https://github.blog/2019-06-06-generate-new-repositories-with-repository-templates/). +[![GitHub Super-Linter](https://github.com/actions/container-toolkit-action/actions/workflows/linter.yml/badge.svg)](https://github.com/super-linter/super-linter) +![Check `dist/`](https://github.com/actions/container-toolkit-action/actions/workflows/check-dist.yml/badge.svg) +![CI](https://github.com/actions/container-toolkit-action/actions/workflows/ci.yml/badge.svg) +[![Code Coverage](./badges/coverage.svg)](./badges/coverage.svg) -For info on how to build your first Container action using the toolkit, see the [toolkit docs folder](https://github.com/actions/toolkit/blob/master/docs). +Use this template to bootstrap the creation of a container action with the +GitHub Actions toolkit. :rocket: + +This template includes compilation support, tests, a validation workflow, +publishing, and versioning guidance. + +For more information on the GitHub Actions toolkit, see the +[`actions/toolkit` repository](https://github.com/actions/toolkit/tree/main/docs) + +## Create Your Own Action + +To create your own action, you can use this repository as a template! Just +follow the below instructions: + +1. Click the **Use this template** button at the top of the repository +1. Select **Create a new repository** +1. Select an owner and name for your new repository +1. Click **Create repository** +1. Clone your new repository + +## Initial Setup + +After you've cloned the repository to your local machine or codespace, you'll +need to perform some initial setup steps before you can develop your action. + +> [!NOTE] +> +> You'll need to have reasonably modern versions of +> [Node.js](https://nodejs.org) and +> [Docker](https://www.docker.com/get-started/) handy (e.g. Node.js v20+ and +> docker engine v20+). + +1. :hammer_and_wrench: Install the dependencies + + ```bash + npm install + ``` + +1. :building_construction: Package the TypeScript for distribution + + ```bash + npm run bundle + ``` + +1. :white_check_mark: Run the tests + + ```bash + $ npm test + + PASS ./index.test.js + ✓ throws invalid number (3ms) + ✓ wait 500 ms (504ms) + ✓ test runs (95ms) + + ... + ``` + +1. :hammer_and_wrench: Build the container + + Make sure to replace `actions/container-toolkit-action` with an appropriate + label for your container. + + ```bash + docker build -t actions/container-toolkit-action . + ``` + +1. :white_check_mark: Test the container + + You can pass individual environment variables using the `--env` or `-e` flag. + + ```bash + $ docker run --env INPUT_MILLISECONDS=2000 actions/container-toolkit-action + ::debug::The event payload: {} + 16:19:19 GMT+0000 (Coordinated Universal Time) + 16:19:21 GMT+0000 (Coordinated Universal Time) + + ::set-output name=time::16:19:21 GMT+0000 (Coordinated Universal Time) + ``` + + Or you can pass a file with environment variables using `--env-file`. + + ```bash + $ cat ./.env.test + INPUT_MILLISECONDS=2000 + + $ docker run --env-file ./.env.test actions/container-toolkit-action + ::debug::The event payload: {} + 16:19:19 GMT+0000 (Coordinated Universal Time) + 16:19:21 GMT+0000 (Coordinated Universal Time) + + ::set-output name=time::16:19:21 GMT+0000 (Coordinated Universal Time) + ``` + +## Update the Action Metadata + +The [`action.yml`](action.yml) file defines metadata about your action, such as +input(s) and output(s). For details about this file, see +[Metadata syntax for GitHub Actions](https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions). + +When you copy this repository, update `action.yml` with the name, description, +inputs, and outputs for your action. + +## Update the Action Code + +### Update the TypeScript Source + +The [`src/`](./src/) directory is the heart of your action! This contains the +source code that will be run when your action is invoked. You can replace the +contents of this directory with your own code. + +There are a few things to keep in mind when writing your action code: + +- Most GitHub Actions toolkit and CI/CD operations are processed asynchronously. + In `main.ts`, you will see that the action is run in an `async` function. + + ```javascript + import * as core from '@actions/core' + //... + + export async function run(): Promise { + try { + //... + } catch (error) { + core.setFailed(error.message) + } + } + ``` + + For more information about the GitHub Actions toolkit, see the + [documentation](https://github.com/actions/toolkit/blob/main/README.md). + +### Update the Container + +In this template, the container action runs a Node.js script, +`node /dist/index.js`, when the container is launched. Since you can choose any +base Docker image and language you like, you can change this to suite your +needs. There are a few main things to remember when writing code for container +actions: + +- Inputs are accessed using argument identifiers or environment variables + (depending on what you set in your `action.yml`). For example, the first input + to this action, `milliseconds`, can be accessed in the Node.js script using + the `process.env.INPUT_MILLISECONDS` environment variable or the + `getInput('milliseconds')` function from the `@actions/core` library. + + ```bash + // Use an action input + const ms: number = parseInt(core.getInput('milliseconds'), 10) + + // Use an environment variable + const ms: number = parseInt(process.env.INPUT_MILLISECONDS, 10) + ``` + +- GitHub Actions supports a number of different workflow commands such as + creating outputs, setting environment variables, and more. These are + accomplished by writing to different `GITHUB_*` environment variables. For + more information, see + [Commands](https://github.com/actions/toolkit/blob/main/docs/commands.md). + + | Scenario | Example | + | -------------------- | --------------------------------------------------- | + | Set environment vars | `core.exportVariable('MY_VAR', 'my-value')` | + | Set outputs | `core.setOutput('time', new Date().toTimeString())` | + | Set secrets | `core.setSecret('mySecret')` | + | Prepend to `PATH` | `core.addPath('/usr/local/bin')` | + +## Publish the Action + +So, what are you waiting for? Go ahead and start customizing your action! + +1. Create a new branch + + ```bash + git checkout -b releases/v1 + ``` + +1. Replace the contents of `src/` with your action code +1. Add tests to `__tests__/` for your source code +1. Format, test, and build the action + + ```bash + npm run all + ``` + + > [!WARNING] + > + > This step is important! It will run [`ncc`](https://github.com/vercel/ncc) + > to build the final JavaScript action code with all dependencies included. + > If you do not run this step, your action will not work correctly when it is + > used in a workflow. This step also includes the `--license` option for + > `ncc`, which will create a license file for all of the production node + > modules used in your project. + +1. Commit your changes + + ```bash + git add . + git commit -m "My first action is ready!" + ``` + +1. Push them to your repository + + ```bash + git push -u origin releases/v1 + ``` + +1. Create a pull request and get feedback on your action +1. Merge the pull request into the `main` branch + +Your action is now published! :rocket: + +For information about versioning your action, see +[Versioning](https://github.com/actions/toolkit/blob/master/docs/action-versioning.md) +in the GitHub Actions toolkit. + +## Validate the Action + +You can now validate the action by referencing it in a workflow file. For +example, [`ci.yml`](./.github/workflows/ci.yml) demonstrates how to reference an +action in the same repository. + +```yaml +steps: + - name: Checkout + id: checkout + uses: actions/checkout@v4 + + - name: Test Local Action + id: test-action + uses: ./ + with: + milliseconds: 1000 + + - name: Print Output + id: output + run: echo "${{ steps.test-action.outputs.time }}" +``` + +For example workflow runs, check out the +[Actions tab](https://github.com/actions/container-toolkit-action/actions)! +:rocket: + +## Usage + +After testing, you can create version tag(s) that developers can use to +reference different stable versions of your action. For more information, see +[Versioning](https://github.com/actions/toolkit/blob/main/docs/action-versioning.md) +in the GitHub Actions toolkit. + +To include the action in a workflow in another repository, you can use the +`uses` syntax with the `@` symbol to reference a specific branch, tag, or commit +hash. + +```yaml +steps: + - name: Checkout + id: checkout + uses: actions/checkout@v4 + + - name: Test Local Action + id: test-action + uses: actions/container-toolkit-action@v1 # Commit with the `v1` tag + with: + milliseconds: 1000 + + - name: Print Output + id: output + run: echo "${{ steps.test-action.outputs.time }}" +```