Skip to content

Commit

Permalink
feat: adds release action
Browse files Browse the repository at this point in the history
  • Loading branch information
jmgilman committed Sep 5, 2024
1 parent af1ae6e commit ce39823
Show file tree
Hide file tree
Showing 20 changed files with 42,525 additions and 40 deletions.
53 changes: 31 additions & 22 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,31 +27,40 @@ jobs:
^check.*
^test.*
publish
release
check:
uses: ./.github/workflows/run.yml
needs: [discover]
with:
earthfiles: ${{ toJson(fromJson(needs.discover.outputs.result)['^check.*']) }}
forge_version: ${{ inputs.forge_version }}
# check:
# uses: ./.github/workflows/run.yml
# needs: [discover]
# with:
# earthfiles: ${{ toJson(fromJson(needs.discover.outputs.result)['^check.*']) }}
# forge_version: ${{ inputs.forge_version }}

build:
uses: ./.github/workflows/run.yml
needs: [discover, check]
with:
earthfiles: ${{ toJson(fromJson(needs.discover.outputs.result)['^build.*']) }}
forge_version: ${{ inputs.forge_version }}
# build:
# uses: ./.github/workflows/run.yml
# needs: [discover, check]
# with:
# earthfiles: ${{ toJson(fromJson(needs.discover.outputs.result)['^build.*']) }}
# forge_version: ${{ inputs.forge_version }}

test:
uses: ./.github/workflows/run.yml
needs: [discover, check, build]
with:
earthfiles: ${{ toJson(fromJson(needs.discover.outputs.result)['^test.*']) }}
forge_version: ${{ inputs.forge_version }}
# test:
# uses: ./.github/workflows/run.yml
# needs: [discover, check, build]
# with:
# earthfiles: ${{ toJson(fromJson(needs.discover.outputs.result)['^test.*']) }}
# forge_version: ${{ inputs.forge_version }}

# publish:
# uses: ./.github/workflows/publish.yml
# needs: [discover, check, build, test]
# with:
# earthfiles: ${{ toJson(fromJson(needs.discover.outputs.result)['publish']) }}
# forge_version: ${{ inputs.forge_version }}

publish:
uses: ./.github/workflows/publish.yml
needs: [discover, check, build, test]
release:
uses: ./.github/workflows/release.yml
#needs: [discover, check, build, test, publish]
needs: [discover]
with:
earthfiles: ${{ toJson(fromJson(needs.discover.outputs.result)['publish']) }}
earthfiles: ${{ toJson(fromJson(needs.discover.outputs.result)['release']) }}
forge_version: ${{ inputs.forge_version }}
57 changes: 57 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
on:
workflow_call:
inputs:
earthfiles:
description: |
A JSON list of Earthfile paths+targets to use for publishing
required: true
type: string
forge_version:
description: |
The version of the forge CLI to install (use 'local' for testing)
required: true
type: string

jobs:
run:
name: ${{ matrix.earthfile }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
earthfile: ${{ fromJson(inputs.earthfiles) }}
steps:
- uses: actions/checkout@v4
- name: Setup CI
uses: ./forge/actions/setup
with:
forge_version: ${{ inputs.forge_version }}
- name: Run
id: run
uses: ./forge/actions/run
with:
artifact: artifacts-out
path: ${{ matrix.earthfile }}
- name: Get project and artifacts
id: artifact
if: startsWith(github.ref, 'refs/tags/')
run: |
EARTHFILE='${{ matrix.earthfile }}'
PROJECT="${EARTHFILE%+*}"
TARGET="${EARTHFILE#*+}"
RESULT='${{ steps.run.outputs.result }}'
ARTIFACT_COUNT="$(echo "$RESULT" | jq -r jq '.artifacts | length')"
if [[ $ARTIFACT_COUNT -eq 0 ]]; then
echo "::error file=${PROJECT}/Earthfile::No artifacts produced. Nothing to release."
exit 1
fi
echo "project=$PROJECT" >> $GITHUB_OUTPUT
- name: Release
uses: ./forge/actions/release
if: startsWith(github.ref, 'refs/tags/')
with:
path: artifacts-out
project: ${{ steps.artifact.outputs.project }}
66 changes: 66 additions & 0 deletions forge/actions/release/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Release Action

The publish action pushes Docker images to remote registries using settings from a project's blueprint file.
It automatically handles the configured tagging strategy as well as properly handling git tags.

## Usage

```yaml
name: Run Publish
on:
push:

permissions:
contents: read
id-token: write

jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Setup
uses: input-output-hk/catalyst-forge/forge/actions/setup@master
- name: Publish
uses: input-output-hk/catalyst-forge/forge/actions/discover@master
with:
project: ./my/project/path
container: container:tag
```
The given project _must_ have a blueprint at the root of the path which, at the very least, declares a project name.
By default, the `container` property of a project uses the project name if not specified.
Alternatively, the `container` field can be set explicitly.
The `container` input to the publish action _must_ match an existing container image in the local Docker daemon.
The given container name is discarded and the value of the `container` field is used for naming the container.

The final tags the container is published with are determined by the blueprint configuration and the git context:

- The `global.ci.tagging.strategy` configuration property determines the default tag given to all images
- If the git context contains a git tag, then the publish action may or may not publish an image with the tag:
- If the tag is in the "mono-repo" style (`some/path/v1.0.0`)
- If the path (`some/path`) matches an alias in `global.ci.tagging.strategy.aliases`, and the value of the alias matches the
given project, then the tag is used
- If the path does not match an alias, but the path itself matches the given project, then the tag is used
- If none of the above are true, the tag is assumed to be for a different project and is skipped
- If the tag is any other style, it's used as-is (no modifications)

The following table provides an example of how the git tag is used in various contexts:

| Project | Git tag | Aliases | Image tag |
| ------------- | -------------------- | ------------------------ | --------- |
| `my/cool/cli` | None | None | Not used |
| `my/cool/cli` | `v1.0.0` | None | `v1.0.0` |
| `my/cool/cli` | `my/v1.0.0` | None | Not used |
| `my/cool/cli` | `my/cool/cli/v1.0.0` | None | `v1.0.0` |
| `my/cool/cli` | `cli/v1.0.0` | `{"cli": "my/cool/cli"}` | `v1.0.0` |

After processing any additional tags, the container is retagged with each generated tag and pushed to all registries configured in
`global.ci.registries`.
The publish action assumes the local Docker daemon is already authenticated to any configured registries.

## Inputs

| Name | Description | Required | Default |
| ------- | ------------------------------------------------ | -------- | ------- |
| project | The relative path to the project (from git root) | Yes | N/A |
| image | The existing container image to publish | Yes | N/A |
21 changes: 21 additions & 0 deletions forge/actions/release/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Release
description: Create a new GitHub release and upload generated artifacts
inputs:
github_token:
description: The token to use for creating a new release
required: false
default: ${{ github.token }}
project:
description: The path to the project
required: true
path:
description: The path to generated artifacts
required: true
platform:
description: The platform the artifacts are targeting
required: false
default: "linux-amd64"

runs:
using: node20
main: dist/index.js
Loading

0 comments on commit ce39823

Please sign in to comment.