Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve documentation #72

Merged
merged 4 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 12 additions & 6 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: daily
{
"updates": [
{
"directory": "/",
"package-ecosystem": "github-actions",
"schedule": {
"interval": "daily"
}
}
],
"version": 2
}
152 changes: 96 additions & 56 deletions .github/workflows/workflow.yaml
Original file line number Diff line number Diff line change
@@ -1,56 +1,96 @@
name: Workflow
on: push
jobs:
image:
strategy:
fail-fast: false
matrix:
include:
- { arch: amd64, ghc: 9.4.7 }
- { arch: amd64, ghc: 9.6.3 }
- { arch: amd64, ghc: 9.8.1 }
- { arch: arm64, ghc: 9.4.7 }
- { arch: arm64, ghc: 9.6.3 }
- { arch: arm64, ghc: 9.8.1 }
runs-on: ubuntu-latest
steps:

- uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-region: ${{ secrets.AWS_DEFAULT_REGION }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

- uses: aws-actions/aws-codebuild-run-build@v1
with:
project-name: docker-haskell-${{ matrix.arch }}
buildspec-override: aws/image.yaml
env-vars-for-codebuild: GHC_VERSION
env:
GHC_VERSION: ${{ matrix.ghc }}

manifest:
needs: image
strategy:
matrix:
ghc:
- 9.4.7
- 9.6.3
- 9.8.1
runs-on: ubuntu-latest
steps:

- uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-region: ${{ secrets.AWS_DEFAULT_REGION }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

- uses: aws-actions/aws-codebuild-run-build@v1
with:
project-name: docker-haskell-amd64
buildspec-override: aws/manifest.yaml
env-vars-for-codebuild: GHC_VERSION,LATEST
env:
GHC_VERSION: ${{ matrix.ghc }}
LATEST: ${{ github.ref == 'refs/heads/main' }}
{
"jobs": {
"image": {
"runs-on": "ubuntu-latest",
"steps": [
{
"uses": "aws-actions/configure-aws-credentials@v4",
"with": {
"aws-access-key-id": "${{ secrets.AWS_ACCESS_KEY_ID }}",
"aws-region": "${{ secrets.AWS_DEFAULT_REGION }}",
"aws-secret-access-key": "${{ secrets.AWS_SECRET_ACCESS_KEY }}"
}
},
{
"env": {
"GHC_VERSION": "${{ matrix.ghc }}"
},
"uses": "aws-actions/aws-codebuild-run-build@v1",
"with": {
"buildspec-override": "aws/image.yaml",
"env-vars-for-codebuild": "GHC_VERSION",
"project-name": "docker-haskell-${{ matrix.arch }}"
}
}
],
"strategy": {
"fail-fast": false,
"matrix": {
"include": [
{
"arch": "amd64",
"ghc": "9.4.7"
},
{
"arch": "amd64",
"ghc": "9.6.3"
},
{
"arch": "amd64",
"ghc": "9.8.1"
},
{
"arch": "arm64",
"ghc": "9.4.7"
},
{
"arch": "arm64",
"ghc": "9.6.3"
},
{
"arch": "arm64",
"ghc": "9.8.1"
}
]
}
}
},
"manifest": {
"needs": "image",
"runs-on": "ubuntu-latest",
"steps": [
{
"uses": "aws-actions/configure-aws-credentials@v4",
"with": {
"aws-access-key-id": "${{ secrets.AWS_ACCESS_KEY_ID }}",
"aws-region": "${{ secrets.AWS_DEFAULT_REGION }}",
"aws-secret-access-key": "${{ secrets.AWS_SECRET_ACCESS_KEY }}"
}
},
{
"env": {
"GHC_VERSION": "${{ matrix.ghc }}",
"LATEST": "${{ github.ref == 'refs/heads/main' }}"
},
"uses": "aws-actions/aws-codebuild-run-build@v1",
"with": {
"buildspec-override": "aws/manifest.yaml",
"env-vars-for-codebuild": "GHC_VERSION,LATEST",
"project-name": "docker-haskell-amd64"
}
}
],
"strategy": {
"matrix": {
"ghc": [
"9.4.7",
"9.6.3",
"9.8.1"
]
}
}
}
},
"name": "Workflow",
"on": "push"
}
59 changes: 54 additions & 5 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,57 @@

This Docker image provides a Haskell development environment with the following tools:

- [GHCup](https://www.haskell.org/ghcup/)
- [GHC](https://www.haskell.org/ghc/)
- [Cabal](https://www.haskell.org/cabal/)
- [Stack](https://docs.haskellstack.org/en/stable/)
- [HLS](https://haskell-language-server.readthedocs.io/en/latest/)
- [GHCup](https://www.haskell.org/ghcup/) version 0.1.20.0
- [GHC](https://www.haskell.org/ghc/) version 9.8.1, 9.6.3, or 9.4.7
- [Cabal](https://www.haskell.org/cabal/) version 3.10.2.0
- [Stack](https://docs.haskellstack.org/en/stable/) version 2.13.1
- [HLS](https://haskell-language-server.readthedocs.io/en/latest/) version 2.4.0.0

## Usage

This Docker image supports both AMD64 (`x86_64`) and ARM64 (`aarch64`) architectures.

To get started, select one of the supported versions of GHC.
The Docker image is available at `public.ecr.aws/acilearning/haskell:$GHC`.
For example, to use GHC 9.8.1 you would use the image `public.ecr.aws/acilearning/haskell:9.8.1`.

Note that the image tag can and often is updated with newer tools.
To pin a specific version, add the commit hash to the end of the tag.
The format is `public.ecr.aws/acilearning/haskell:$GHC-$COMMIT`.
For example, to use GHC 9.8.1 at a specific commit you would use the image `public.ecr.aws/acilearning/haskell:9.8.1-3a8c34f81332de06c4c2239e144a63dfd11de9f0`.
This is recommended for reproducible builds.

## Development Container

This Docker image is designed to be used as a [Development Container](https://containers.dev/).

Here is an example `.devcontainer.json` file:

``` json
{
"customizations": { "vscode": { "extensions": [ "haskell.haskell" ] } },
"dockerComposeFile": "compose.yaml",
"postCreateCommand": "cabal update",
"postStartCommand": "git config --global --add safe.directory \"$PWD\"",
"service": "devcontainer",
"workspaceFolder": "/workspace"
}
```

And the corresponding `compose.yaml` file:

``` yaml
services:
devcontainer:
command: sleep infinity
image: public.ecr.aws/acilearning/haskell:9.8.1-3a8c34f81332de06c4c2239e144a63dfd11de9f0
init: true
volumes: [ .:/workspace ]
working_dir: /workspace
```

Depending on your specific scenario, you may want to create volumes one or more of the following directories:

- Cabal's cache: `/home/vscode/.cache/cabal`
- Cabal's state: `/home/vscode/.local/state/cabal` (can be an external volume shared between projects)
- Stack's share: `/home/vscode/.local/share/stack`
59 changes: 28 additions & 31 deletions aws/image.yaml
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
version: 0.2
env:
secrets-manager:
DOCKER_PASSWORD: docker-hub-read-only:DOCKER_PASSWORD
DOCKER_USERNAME: docker-hub-read-only:DOCKER_USERNAME
variables:
AWS_REGION: us-east-1
# These values are simply the defaults. They are typically overriden by the
# workflow in `.github/workflows/workflow.yaml`.
GHC_VERSION: 9.8.1
phases:
build:
commands:

- echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin

- server=public.ecr.aws/acilearning

- aws ecr-public get-login-password --region "$AWS_REGION" | docker login --username AWS --password-stdin "$server"

- case $( uname -m ) in ( aarch64 ) arch=arm64 ;; ( x86_64 ) arch=amd64 ;; ( * ) exit 1 ;; esac

- echo "$arch"

- tag="$server/haskell:$GHC_VERSION-$CODEBUILD_RESOLVED_SOURCE_VERSION-$arch"

- echo "$tag"

- docker build --build-arg GHC_VERSION="$GHC_VERSION" --tag "$tag" .

- docker push "$tag"
{
"env": {
"secrets-manager": {
"DOCKER_PASSWORD": "docker-hub-read-only:DOCKER_PASSWORD",
"DOCKER_USERNAME": "docker-hub-read-only:DOCKER_USERNAME"
},
"variables": {
"AWS_REGION": "us-east-1",
"GHC_VERSION": "9.8.1"
}
},
"phases": {
"build": {
"commands": [
"echo \"$DOCKER_PASSWORD\" | docker login --username \"$DOCKER_USERNAME\" --password-stdin",
"server=public.ecr.aws/acilearning",
"aws ecr-public get-login-password --region \"$AWS_REGION\" | docker login --username AWS --password-stdin \"$server\"",
"case $( uname -m ) in ( aarch64 ) arch=arm64 ;; ( x86_64 ) arch=amd64 ;; ( * ) exit 1 ;; esac",
"echo \"$arch\"",
"tag=\"$server/haskell:$GHC_VERSION-$CODEBUILD_RESOLVED_SOURCE_VERSION-$arch\"",
"echo \"$tag\"",
"docker build --build-arg GHC_VERSION=\"$GHC_VERSION\" --tag \"$tag\" .",
"docker push \"$tag\""
]
}
},
"version": 0.2
}
53 changes: 23 additions & 30 deletions aws/manifest.yaml
Original file line number Diff line number Diff line change
@@ -1,30 +1,23 @@
version: 0.2
env:
variables:
AWS_REGION: us-east-1
# These values are simply the defaults. They are typically overriden by
# the workflow in `.github/workflows/workflow.yaml`.
GHC_VERSION: 9.8.1
LATEST: 'false'
phases:
build:
commands:

- server=public.ecr.aws/acilearning

- aws ecr-public get-login-password --region "$AWS_REGION" | docker login --username AWS --password-stdin "$server"

- tag="$server/haskell:$GHC_VERSION-$CODEBUILD_RESOLVED_SOURCE_VERSION"

- echo "$tag"

- docker manifest create "$tag" "$tag-amd64" "$tag-arm64"

- docker manifest push "$tag"

- if test "$LATEST" = 'true';
then latest="$server/haskell:$GHC_VERSION";
echo "$latest";
docker manifest create "$latest" "$tag-amd64" "$tag-arm64";
docker manifest push "$latest";
fi
{
"env": {
"variables": {
"AWS_REGION": "us-east-1",
"GHC_VERSION": "9.8.1",
"LATEST": "false"
}
},
"phases": {
"build": {
"commands": [
"server=public.ecr.aws/acilearning",
"aws ecr-public get-login-password --region \"$AWS_REGION\" | docker login --username AWS --password-stdin \"$server\"",
"tag=\"$server/haskell:$GHC_VERSION-$CODEBUILD_RESOLVED_SOURCE_VERSION\"",
"echo \"$tag\"",
"docker manifest create \"$tag\" \"$tag-amd64\" \"$tag-arm64\"",
"docker manifest push \"$tag\"",
"if test \"$LATEST\" = 'true'; then latest=\"$server/haskell:$GHC_VERSION\"; echo \"$latest\"; docker manifest create \"$latest\" \"$tag-amd64\" \"$tag-arm64\"; docker manifest push \"$latest\"; fi"
]
}
},
"version": 0.2
}