Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
105c86b
Merge pull request #40 from FireTail-io/dev
santhoshfiretail Oct 16, 2023
806376e
feat: Publish to GHCR rather than ECR
gregalia Oct 19, 2023
e53dd13
docs: Format README
gregalia Oct 19, 2023
66c8235
Merge pull request #41 from FireTail-io/feat/fire-1839/publish-to-ghcr
gregalia Oct 19, 2023
01e4c21
ci: Fix image name
gregalia Oct 19, 2023
f132125
docs: README minutiae
gregalia Oct 19, 2023
bec1fc6
Merge pull request #42 from FireTail-io/feat/fire-1839/publish-to-ghcr
rileyfiretail Oct 19, 2023
b5175f6
ci: Lowercase docker image tag
gregalia Oct 19, 2023
253a661
Merge branch 'main' into feat/fire-1839/publish-to-ghcr
gregalia Oct 19, 2023
7411a55
Merge pull request #43 from FireTail-io/feat/fire-1839/publish-to-ghcr
rileyfiretail Oct 19, 2023
b8a040c
ci: Provide argument to awk
gregalia Oct 19, 2023
0414ad9
Merge pull request #44 from FireTail-io/feat/fire-1839/publish-to-ghcr
rileyfiretail Oct 19, 2023
911d154
ci: Permit workflows to publish to ghcr.io
gregalia Oct 19, 2023
ce3e020
Merge pull request #45 from FireTail-io/feat/fire-1839/publish-to-ghcr
gregalia Oct 19, 2023
127f891
ci: Fix perms for release-drafter/release-drafter
gregalia Oct 19, 2023
d4c737e
Merge pull request #46 from FireTail-io/feat/fire-1839/publish-to-ghcr
rileyfiretail Oct 19, 2023
cf49708
feat: Do not publish lambda image
gregalia Oct 19, 2023
cfd6969
docs: Update for GHCR image-based usage
gregalia Oct 19, 2023
e8ab0d4
docs: Wrap README lines
gregalia Oct 20, 2023
f5eb088
docs: Update README with fine-grained token usage
gregalia Oct 20, 2023
286fd7a
Merge pull request #47 from FireTail-io/feat/fire-1839/publish-to-ghcr
rileyfiretail Oct 20, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 43 additions & 29 deletions .github/workflows/draft-release.yml
Original file line number Diff line number Diff line change
@@ -1,56 +1,70 @@
name: Draft Release On Push To Main And Push Prerelease Image To ECR
name: Draft Release
run-name: '@${{ github.triggering_actor }}: ${{ github.ref_name }}: ${{ github.event_name }}'

on:
push:
branches:
- main

env:
AWS_REGION: us-east-1
ECR_REGISTRY: public.ecr.aws/x7v5r9e4
ECR_REPOSITORY: firetail-code-repository-scanner

REGISTRY: ghcr.io
IMAGE_NAME: firetail-code-repository-scanner

jobs:
draft-release:
name: Draft Release

runs-on: ubuntu-latest

permissions:
id-token: write
contents: write
packages: write
pull-requests: write

steps:
- name: Checkout
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Draft Release
id: draft_release
uses: release-drafter/release-drafter@569eb7ee3a85817ab916c8f8ff03a5bd96c9c83e
uses: release-drafter/release-drafter@09c613e259eb8d4e7c81c2cb00618eb5fc4575a7 # v5.25.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@67fbcbb121271f7775d2e7715933280b06314838
with:
aws-region: ${{ env.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_ACCOUNT_ROLE_ARN }}
role-session-name: git-api-discovery-publish-action-draft
- name: Set Image Tags From Release Output
run: |
NAMESPACE="$(awk '{print(tolower($0))}' <<<${{ github.repository_owner }})"
cat <<HEREDOC >>${GITHUB_ENV}
TAG_BASE=${{ env.REGISTRY }}/${NAMESPACE}/${{ env.IMAGE_NAME }}
PRERELEASE_IMAGE_TAG=${{ steps.draft_release.outputs.tag_name }}-prerelease
PRERELEASE_LAMBDA_IMAGE_TAG=${{ steps.draft_release.outputs.tag_name }}-lambda-prerelease
HEREDOC

- name: Login to ECR and build, tag & push prerelease images
env:
PRERELEASE_IMAGE_TAG: ${{ steps.draft_release.outputs.tag_name }}-prerelease
PRERELEASE_LAMBDA_IMAGE_TAG: ${{ steps.draft_release.outputs.tag_name }}-lambda-prerelease
- name: Log In to the Container Registry
run: |
docker login ${{ env.REGISTRY }} \
--username ${{ github.actor }} \
--password-stdin <<<${{ secrets.GITHUB_TOKEN }}

- name: Build and Push Runtime Image
run: |
docker build \
--target runtime \
--tag ${{ env.TAG_BASE }}:${{ env.PRERELEASE_IMAGE_TAG }} \
--file build_setup/Dockerfile \
"${PWD}"
docker tag ${{ env.TAG_BASE }}:${{ env.PRERELEASE_IMAGE_TAG }} \
${{ env.TAG_BASE }}:latest-prerelease
docker push ${{ env.TAG_BASE }}:${{ env.PRERELEASE_IMAGE_TAG }}
docker push ${{ env.TAG_BASE }}:latest-prerelease

- name: Summarize Workflow Run
run: |
aws ecr-public get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin public.ecr.aws
docker build --target runtime -t $ECR_REGISTRY/$ECR_REPOSITORY:$PRERELEASE_IMAGE_TAG -f build_setup/Dockerfile .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$PRERELEASE_IMAGE_TAG
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$PRERELEASE_IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:latest-prerelease
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$PRERELEASE_IMAGE_TAG
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest-prerelease
docker build --target runtime-lambda -t $ECR_REGISTRY/$ECR_REPOSITORY:$PRERELEASE_LAMBDA_IMAGE_TAG -f build_setup/Dockerfile .
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$PRERELEASE_LAMBDA_IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:latest-lambda-prerelease
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$PRERELEASE_LAMBDA_IMAGE_TAG
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest-lambda-prerelease
echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$PRERELEASE_IMAGE_TAG" >> $GITHUB_OUTPUT
cat <<HEREDOC >>${GITHUB_STEP_SUMMARY}
## Successfully Pushed:

- ${{ env.TAG_BASE }}:${{ env.PRERELEASE_IMAGE_TAG }}
- ${{ env.TAG_BASE }}:latest-prerelease
- ${{ env.TAG_BASE }}:${{ env.PRERELEASE_LAMBDA_IMAGE_TAG }}
- ${{ env.TAG_BASE }}:latest-lambda-prerelease
HEREDOC
76 changes: 36 additions & 40 deletions .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
@@ -1,56 +1,52 @@
name: Pull Prerelease Image From ECR And Push As Release Image When Draft Release Is Published

name: Publish Release
run-name: '@${{ github.triggering_actor }}: ${{ github.ref_name }}: ${{ github.event_name }}: ${{ github.event.action }}'
on:
release:
types: [published]

env:
AWS_REGION: us-east-1
ECR_REGISTRY: public.ecr.aws/x7v5r9e4
ECR_REPOSITORY: firetail-code-repository-scanner
REGISTRY: ghcr.io
IMAGE_NAME: firetail-code-repository-scanner

jobs:
publish-release:
name: Publish Release

environment: prod

runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
pull-requests: write
packages: write

steps:
- name: Get release
id: get_release
uses: bruceadams/get-release@74c3d60f5a28f358ccf241a00c9021ea16f0569f
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@67fbcbb121271f7775d2e7715933280b06314838
with:
aws-region: ${{ env.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_ACCOUNT_ROLE_ARN }}
role-session-name: git-api-discovery-publish-action-prod

- name: Pull prerelease images from ECR, retag them as a releases, and push them back to ECR with their new tags
id: build-image
env:
PRERELEASE_IMAGE_TAG: ${{ steps.get_release.outputs.tag_name }}-prerelease
PRERELEASE_LAMBDA_IMAGE_TAG: ${{ steps.get_release.outputs.tag_name }}-lambda-prerelease
IMAGE_TAG: ${{ steps.get_release.outputs.tag_name }}
LAMBDA_IMAGE_TAG: ${{ steps.get_release.outputs.tag_name }}-lambda

- name: Set Image Tags
run: |
NAMESPACE="$(awk '{print(tolower($0))}' <<<${{ github.repository_owner }})"
echo "TAG_BASE=${{ env.REGISTRY }}/${NAMESPACE}/${{ env.IMAGE_NAME }}" >>${GITHUB_ENV}

- name: Log In to the Container Registry
run: |
aws ecr-public get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin public.ecr.aws
docker pull $ECR_REGISTRY/$ECR_REPOSITORY:$PRERELEASE_IMAGE_TAG
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$PRERELEASE_IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$PRERELEASE_IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:latest
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
docker pull $ECR_REGISTRY/$ECR_REPOSITORY:$PRERELEASE_LAMBDA_IMAGE_TAG
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$PRERELEASE_LAMBDA_IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:$LAMBDA_IMAGE_TAG
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$LAMBDA_IMAGE_TAG
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$PRERELEASE_LAMBDA_IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:latest-lambda
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest-lambda
echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
docker login ${{ env.REGISTRY }} \
--username ${{ github.actor }} \
--password-stdin <<<${{ secrets.GITHUB_TOKEN }}

- name: Publish Prelease Lambda Image as Full Release
run: |
docker pull ${{ env.TAG_BASE }}:${{ github.ref_name }}-prerelease
docker tag ${{ env.TAG_BASE }}:${{ github.ref_name }}-prerelease \
${{ env.TAG_BASE }}:${{ github.ref_name }}
docker tag ${{ env.TAG_BASE }}:${{ github.ref_name }}-prerelease \
${{ env.TAG_BASE }}:latest
docker push ${{ env.TAG_BASE }}:${{ github.ref_name }}
docker push ${{ env.TAG_BASE }}:latest

- name: Summarize Workflow Run
run: |
cat <<HEREDOC >>${GITHUB_STEP_SUMMARY}
## Successfully Pushed:

- ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
- ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}-lambda
- ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest-lambda
HEREDOC
124 changes: 70 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,82 @@
# API Discovery from Github Repositories

This Docker image will discover APIs in your GitHub account by scanning for openapi/swagger specifications in your repositories, as well as generating them via static code analysis. It will create an API per repository, and potentially multiple collections for that API, in the FireTail SaaS Platform.



## Quickstart

First, clone this repo and build the scanner's image:

```bash
git clone git@github.com:FireTail-io/github-api-discovery.git
cd github-api-discovery
docker build --rm -t firetail-io/github-api-discovery:latest -f build_setup/Dockerfile . --target runtime
```

Make a copy of the provided [config-example.yml](./config-example.yml) and call it `config.yml`, then edit it for your use case.

```bash
cp config-example.yml config.yml
open config.yml
# API Discovery From GitHub Repositories

This Docker image will discover APIs in your GitHub organization/account by scanning for
OpenAPI/Swagger specifications in your repositories, as well as generating them via static code
analysis. It will create an API per repository, and potentially multiple collections for that API,
in the FireTail SaaS Platform.

## Requirements

- A 'classic' GitHub access token with `read:packages` scope
- Fine-grained tokens do not currently support any `packages` scopes
([link](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-to-the-container-registry))
- Any type of GitHub access token with `read: contents` scope for the repos you wish to scan
([link](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens))
- If you use a fine-grained GitHub access token scoped to specific repos, you will have to list
them individually
- A FireTail app token ([link](https://www.firetail.io/docs/create-app-token))

## Configure The Scanner

Create a file named `config.yml` (not `.yaml`) from the following:

```yaml
# List organisations to scan their repositories
organisations: # default []
example-organisation:
# Under each org, you can skip public, private, internal, archived or fork repositories
skip_public_repositories: False # default False
skip_private_repositories: False # default False
skip_internal_repositories: False # default False
skip_archived_repositories: False # default False
skip_forks: False # default False

# List users to scan their repositories
users: # default []
example-user:
# Under each user, you can skip public, private, archived or fork repositories
skip_public_repositories: False # default False
skip_private_repositories: False # default False
skip_archived_repositories: False # default False
skip_forks: False # default False

# List individual repositories to include or exclude explicitly - has higher
# precedence than scanning via users or orgs
repositories: # default []
example-user/example-repository: exclude
example-organisation/example-repository: include
```

Running the image requires two environment variables to be set:
Use the `repositories` block when using a fine-grained access token without access to all repos.

- `GITHUB_TOKEN`, [a classic GitHub personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic).
- `FIRETAIL_APP_TOKEN`, [a FireTail app token](https://www.firetail.io/docs/create-app-token).
## Run the Scanner

Find a full list of environment variables under [Environment Variables](#environment-variables).
Authenticate your docker CLI ([link](https://docs.docker.com/engine/reference/commandline/login/))

Once you have created a classic GitHub personal access token and a FireTail app token, you can run the scanner image:

```bash
export GITHUB_TOKEN=YOUR_GITHUB_TOKEN
export FIRETAIL_APP_TOKEN=YOUR_FIRETAIL_APP_TOKEN
docker run --rm -e GITHUB_TOKEN=${GITHUB_TOKEN} -e FIRETAIL_APP_TOKEN=${FIRETAIL_APP_TOKEN} --mount type=bind,source="$(pwd)"/config.yml,target=/config.yml,readonly firetail-io/github-api-discovery:latest
```shell
docker login \
--username ${YOUR_GITHUB_USERNAME} \
--password ${YOUR_GITHUB_CLASSIC_TOKEN} \
ghcr.io
```

Start the scan


## Tests

The tests can be run using the provided Dockerfile:

```bash
docker build --rm -t firetail-io/github-api-discovery:test-python -f build_setup/Dockerfile . --target test-python
```shell
docker run --rm \
--env GITHUB_TOKEN=${YOUR_GITHUB_TOKEN} \
--env FIRETAIL_APP_TOKEN=${YOUR_FIRETAIL_APP_TOKEN} \
--mount type=bind,source="${PWD}/config.yml",target=/config.yml,readonly \
ghcr.io/firetail-io/firetail-code-repository-scanner:latest
```

Tests for the Golang analyser can also be run separately using the provided Dockerfile to yield a html coverage report:

```bash
docker build --rm -t firetail-io/github-api-discovery:test-golang -f build_setup/Dockerfile . --target test-golang
docker run --rm --entrypoint cat firetail-io/github-api-discovery:test-golang coverage.html > golang-coverage.html
```



## Environment Variables
## Container Environment Variables

| Variable Name | Description | Required? | Default |
| -------------------- | ------------------------------------------------------------ | --------- | ------------------------------------------------ |
| `GITHUB_TOKEN` | A classic GitHub personal access token. | Yes ✅ | None |
| `FIRETAIL_APP_TOKEN` | An app token from the Firetail SaaS. | Yes ✅ | None |
| `FIRETAIL_API_URL` | The URL of the Firetail SaaS' API. | No ❌ | `"https://api.saas.eu-west-1.prod.firetail.app"` |
| `LOGGING_LEVEL` | The logging level provided to python's [logging](https://docs.python.org/3/library/logging.html#logging-levels) library. | No ❌ | `"INFO"` |
Set via the `--env` flag when executing `docker run`

| Variable Name | Description | Required? | Default |
| -------------------- | ----------------------------------------------------------------------------------------------- | --------- | ---------------------------------------------- |
| `GITHUB_TOKEN` | A GitHub access token | Yes ✅ | None |
| `FIRETAIL_APP_TOKEN` | A FireTail app token | Yes ✅ | None |
| `FIRETAIL_API_URL` | The API URL for your FireTail SaaS instance | No ❌ | `https://api.saas.eu-west-1.prod.firetail.app` |
| `LOGGING_LEVEL` | The scanner's verbosity ([link](https://docs.python.org/3/library/logging.html#logging-levels)) | No ❌ | `INFO` |
4 changes: 2 additions & 2 deletions config-example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ users: # default []
skip_archived_repositories: False # default False
skip_forks: False # default False

# List individual repositories to include or exclude them explicitly from scanning.
# Has higher prescedence than scanning via users or orgs.
# List individual repositories to include or exclude explicitly - has higher
# precedence than scanning via users or orgs
repositories: # default []
example-user/example-repository: exclude
example-organisation/example-repository: include