Skip to content

Commit

Permalink
feat: init project (#1)
Browse files Browse the repository at this point in the history
* feat: init project
  • Loading branch information
kperreau committed Apr 19, 2024
1 parent aa3725a commit 9fa7d20
Show file tree
Hide file tree
Showing 46 changed files with 4,547 additions and 2 deletions.
17 changes: 17 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.gitignore
.dockerignore
Dockerfile
.github/
.git/
*.log
.goac/
.goacproject.yaml
.semver.yaml
coverage.out
goac
*_test.go
README.md
LICENSE
Makefile
.DS_Store
.idea
2 changes: 2 additions & 0 deletions .github/auto_assign.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
addReviewers: false
addAssignees: author
29 changes: 29 additions & 0 deletions .github/workflows/auto-clean-cache.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Cleanup branch caches
on:
pull_request:
types:
- closed

jobs:
autoCleanup:
runs-on: ubuntu-latest
steps:
- name: Cleanup
run: |
gh extension install actions/gh-actions-cache
echo "Fetching list of cache key"
cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH -L 100 | cut -f 1 )
## Setting this to not fail the workflow while deleting cache keys.
set +e
echo "Deleting caches..."
for cacheKey in $cacheKeysForPR
do
gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm
done
echo "Done"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge
49 changes: 49 additions & 0 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Main

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

on:
push:
branches:
- "**"

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.22"
cache: false
check-latest: true

- name: Verify dependencies
run: |
go mod verify
git diff --exit-code
- name: golangci-lint
uses: golangci/golangci-lint-action@v4
with:
version: "v1.55.2"
args: --timeout=10m

- name: Vet
run: make vet

- name: Test Format
run: |
go install mvdan.cc/gofumpt@latest
make format
- name: Unit Test
run: make ci-test
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@

# Go workspace file
go.work

.goac
goac
.idea
.DS_Store
18 changes: 18 additions & 0 deletions .goacproject.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: "1.0"
name: goac
target:
build:
exec:
cmd: go
params:
- build
- -ldflags=-s -w
- -o
- '{{project-path}}/{{project-name}}'
- '{{project-path}}'
build-image:
envs:
- key: PROJECT_PATH
value: '{{project-path}}'
exec:
cmd: ./_scripts/build-image.sh
4 changes: 4 additions & 0 deletions .semver.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
alpha: 0
beta: 0
rc: 0
release: v1.0.0
21 changes: 21 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM golang:1.22-bookworm AS builder

# Set Go env
ENV GOOS=linux CGO_ENABLED=0

WORKDIR /workspace

# Build Go binary
COPY . .
RUN --mount=type=cache,mode=0755,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
go mod download
RUN --mount=type=cache,mode=0755,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
CGO_ENABLED=0 go build -ldflags="-s -w" -o /workspace/goac

# Deployment container
FROM gcr.io/distroless/static-debian12

COPY --from=builder /workspace/goac /goac
ENTRYPOINT ["/goac"]
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
24 changes: 24 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
tidy:
@go mod tidy
@gofumpt -l -w .

test:
@go test ./...

test-coverage:
go test ./... -coverprofile=coverage.out

dep:
go mod download

vet:
@go vet -unsafeptr=false ./...

lint:
@golangci-lint run

ci-test:
@go test -race -vet=off ./...

format:
@gofumpt -l .
190 changes: 189 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,189 @@
# goac
# Go Affected Cache (GOAC)

## 📖 About
Go Affected Cache (GOAC) is a tool tailored to optimize the build process for binaries and Docker images in monorepo setups through caching.

It generates and caches a hash based on the list of dependencies and files imported by each project within the monorepo. This functionality prevents unnecessary builds by detecting changes accurately, thus conserving time and resources.

Originally developed to address specific needs in my own project's architecture, GOAC might not directly align with every user's project structure and requirements, making its utility somewhat experimental.

## 🌟 Features
Monorepo Efficiency: Specifically designed for monorepos, ensuring efficient handling of multiple interconnected projects.
Intelligent Change Detection: Utilizes hashes of dependencies and files to determine the necessity of builds.
Docker Integration: Optimizes Docker image creation by avoiding unnecessary builds and pushes, preventing redundant deployments.

## 🛠 Installation
Follow these steps to install GOAC in your environment. Adjust as necessary for your specific setup.

```bash
go install github.com/kperreau/goac@latest
```

## ⚙️ Configuration
Configuring GOAC is straightforward. You need to create a `.goacproject.yaml` file and place it at the root of each project/directory that requires a build.

### File example:
```yaml
# .goacproject.yaml

version: 1.0 # Please do not modify this value; keep it set to 1.0
name: goac # Specify the name of your project, service, or application here
target: # GOAC currently supports two targets: 'build' and 'build-image'
build: # This target compiles the Go binary
exec:
cmd: go # The command to execute for compilation; 'go' in this case
params: # Parameters to be added; the final command will be: go build -ldflags="-s -w" -o ./goac goac
- build
- -ldflags=-s -w
- -o
- "{{project-path}}/{{project-name}}"
- "{{project-path}}"
build-image: # This target builds the Docker image
envs:
- key: PROJECT_PATH
value: "{{project-path}}"
exec:
cmd: ./_scripts/build-image.sh # Shell script to execute for building the image
```
To see what the script that builds the image of this project looks like, take a look at this example: [build-image.sh](./_scripts/build-image.sh)
### Variables
The configuration file interprets variables that will automatically be replaced by their values at runtime, it works for env value and params.
| Variable | Type | Description |
|:-------------------| :------- |:------------------------|
| `{{project-name}}` | `string` | The name of the project |
| `{{project-path}}` | `string` | The path of the project |

## 🚀 Usage
GOAC offers commands such as affected and list to manage your monorepo effectively.

**⚠️ Important: To works properly, GOAC must be executed from the root directory of your project, where the `go.mod` file is located.**

```
Usage:
goac [command]

Available Commands:
affected List affected projects
completion Generate the autocompletion script for the specified shell
discover List discovered projects
help Help about any command
list List projects

Flags:
-h, --help help for goac
```
### Checking / Building Affected Projects
```
List projects affected by recent changes based on GOAC cache.

Usage:
goac affected [flags]

Examples:
goac affected -t build

Flags:
--binarycheck Affected if binary is missing
-c, --concurrency int Max Concurrency (default 4)
--debug string Display some data to debug
--dockerignore Read docker ignore (default true)
--dryrun Dry & run
-f, --force Force build
-h, --help help for affected
-p, --projects string Filter by projects name
--stdout Print stdout of exec command
-t, --target string Target
```
#### Debug Options
```
--debug [types]: Controls the verbosity of command output, useful for debugging.
Available types: name,includes,excludes,local,dependencies
```
#### Exemples:
```bash
goac affected -t build # build binary of affected project
goac affected -t build -p auth,user # build binaries for auth and user service
goac affected -t build --force # build all binaries without checking affected projects
goac affected -t build --debug=name,hashed -p docs # build project docs with debug to display project name and hashed files
```

### Listing Projects
List all projects configured in your monorepo based on the `.goacproject.yaml`:

```
Use it to list all your projects configured with GOAC.
Usage:
goac list [flags]
Examples:
goac list
Flags:
-c, --concurrency int Max Concurrency (default 4)
-h, --help help for list
-p, --projects string Filter by projects name
```
#### Exemples:
```bash
goac list
goac list -p goac
```


### Discover Projects
GOAC can explore your repository to identify potential projects and automatically generate a default `.goacproject.yaml` configuration file per project.

```
Use it to discovering projects and create default config files.
Usage:
goac discover [flags]
Examples:
goac discover
Flags:
-c, --create Create project config files
-f, --force Force creation file if already exist
-h, --help help for discover
```

#### Exemples:
```bash
goac discover
goac discover -c
```

#### Automatic Project Naming and Configuration
GOAC automatically generates a project name in each configuration file based on the directory path.
Additionally, the default configuration executes the [build-image.sh](./_scripts/build-image.sh) script for the build-image target.
Please note that this script is not created by default in your repository. You will need to either modify the configuration or create your own script.

## 📘 Note
The Dockerfile and its interpretation are crucial for GOAC.
It allows excluding all unused files, especially those likely to be generated and impact the cache, thereby potentially affecting the project indefinitely.
Make sure to exclude files that are not necessary, such as the `.git`, `.idea`, `.vscode`, etc.

For reference, see this [Dockerfile](Dockerfile)


## 👨‍💻 Contribution
Contributions are welcome! If you'd like to contribute, please follow these steps:

Fork the project
Create your feature branch (git checkout -b feature/AmazingFeature)
Commit your changes (git commit -m 'Add some AmazingFeature')
Push to the branch (git push origin feature/AmazingFeature)
Open a Pull Request

## 📝 Authors
- [@kperreau](https://www.github.com/kperreau)

## 📄 License
Distributed under the MIT License. See [LICENSE](./LICENSE) for more information.
Loading

0 comments on commit 9fa7d20

Please sign in to comment.