diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..906dc367 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,38 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-docker-compose +{ + "name": "bootstrap_form", + + // Update the 'dockerComposeFile' list if you have more compose files or use different names. + "dockerComposeFile": ["../compose.yml", "../compose.override.yml"], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "shell", + + // The optional 'workspaceFolder' property is the path VS Code should open by default when + // connected. This is typically a file mount in .devcontainer/docker-compose.yml + "workspaceFolder": "/app", + // "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}" + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Uncomment the next line if you want start specific services in your Docker Compose config. + // "runServices": [], + + // Uncomment the next line if you want to keep your containers running after VS Code shuts down. + "shutdownAction": "none" + + // Uncomment the next line to run commands after the container is created. + // "postCreateCommand": "cat /etc/os-release", + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as an existing user other than the container default. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "reid" +} diff --git a/.gitignore b/.gitignore index 335a89d7..89073e7a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,14 +4,21 @@ .npm/_npx .idea -log/*.log -pkg/ +/doc/ +/log/*.log +/pkg/ +/tmp/ + demo/db/*.sqlite3 demo/db/*.sqlite3-shm demo/db/*.sqlite3-wal demo/doc/screenshots/**/*.diff.png demo/log/*.log +demo/storage demo/tmp/ + +test/dummy/ + *.gem .rbenv-gemsets *.swp @@ -27,10 +34,6 @@ Vagrantfile # For the demo app. -# Ignore uploaded files in development. -demo/storage/* -!demo/storage/.keep - demo/public/assets **/.byebug_history @@ -47,7 +50,7 @@ demo/.yarn-integrity demo/vendor/bundle # For stuff that gets created if using the Dockerfile image -.bundle/ +/.bundle/ .cache/ vendor/bundle @@ -62,4 +65,12 @@ vendor/bundle .ash_history .sqlite_history +compose.override.yml docker-compose.override.yml + +.vscode-server/ +.dotnet/ +.gnupg/ +.ssh/ +.gitconfig + diff --git a/.yarnrc b/.yarnrc index 60afeac1..f2935e18 100644 --- a/.yarnrc +++ b/.yarnrc @@ -2,4 +2,4 @@ # yarn lockfile v1 -lastUpdateCheck 1698606246341 +lastUpdateCheck 1709415989700 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ac590079..00e9f4b9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -76,7 +76,7 @@ cd demo bundle exec rails test:all # or test:system ``` -The [Docker development environment](#using-docker-compose) appears to generate screenshots that are the same as what GitHub generates. +The [Docker development environment](#using-docker compose) appears to generate screenshots that are the same as what GitHub generates. Finally, maintainers may sometimes push changes directly to `main` or use other workflows to update the code. If pushing to `main` generates a commit for screenshot changes, please consider reverting your change immediately by executing the above `pull` and `revert` and another `push`, for the sanity of users who are using the edge (`main` branch) version of the gem. At any rate, review the changes promptly and use your judgement. @@ -104,116 +104,11 @@ The Ruby on Rails support policy is [here](https://guides.rubyonrails.org/mainte ### Developing with Docker -This repository offers experimental support support for a couple of ways to develop using Docker, if you're interested: +This repository offers experimental support for development using Docker. Docker is _not_ required to do development work on this gem. -- Using `docker-compose`. This way is less tested, and is an attempt to make the Docker container a more complete environment where you can conveniently develop and release the gem. -- Using just a simple Dockerfile. This way works for simple testing, but doesn't make it easy to release the gem, among other things. +One advantage of the Docker environment is that it allows you to generate and compare the screenshots with the expected screenshots in the repo. It also allows you to develop in an environment that is isolated from your own computer's set-up, so there's less risk of breaking other things you might be doing with your computer. -Docker is _not_ required to work on this gem. - -#### Using `docker-compose` - -The `docker-compose` approach should link to enough of your networking configuration that you can release the gem. -However, you have to do some of the configuration yourself, because it's dependent on your host operating system. - -First, build the image for whatever version of Ruby you need (typically either the earliest supported version or the latest): - -```bash -RUBY_VERSION=3.2 docker-compose build -``` - -You can run a shell in a Docker container that pretty much should behave like a Debian distribution with: - -```bash -docker-compose run --service-ports shell -``` - -(`--service-ports` exposes port 3000 so you can browse to the demo app on `localhost:3000`. If you just want to run a one-off command, or run the test suite, leave off the `--service-ports`.) - -The following instructions work for an Ubuntu host, and will probably work for other common Linux distributions. - -Add a `docker-compose.override.yml` in the local directory, that looks like this: - -```docker-compose.yml -version: '3.3' - -# https://blog.giovannidemizio.eu/2021/05/24/how-to-set-user-and-group-in-docker-compose/ - -services: - shell: - # You have to set the user and group for this process, because you're going to be - # creating all kinds of files from inside the container, that need to persist - # outside the container. - # Change `1000:1000` to the user and default group of your laptop user. - user: 1000:1000 - volumes: - - /etc/passwd:/etc/passwd:ro - - ~/.gem/credentials:/app/.gem/credentials:ro - # $HOME here is your host computer's `~`, e.g. `/home/reid`. - # `ssh` explicitly looks for its config in the home directory from `/etc/passwd`, - # so the target for this has to look like your home directory on the host. - - ~/.ssh:${HOME}/.ssh:ro - - ${SSH_AUTH_SOCK}:/ssh-agent - environment: - - SSH_AUTH_SOCK=/ssh-agent -``` - -You may have to change the `1000:1000` to the user and group IDs of your laptop. You may also have to change the `version` parameter to match the version of the `docker-compose.yml` file. - -Adapting the above `docker-compose.override.yml` for MacOS should be relatively straight-forward. Windows users, I'm afraid you're on your own. If you figure this out, a PR documenting how to do it would be most welcome. - -The above doesn't allow you to run the system tests. To keep the image small, it doesn't include Chrome or any other browser. - -There is an experimental `docker-compose-system-test.yml` file, that runs the `bootstrap_forms` docker container along with an off-the-shelf Selenium container. To start this configuration: - -```bash -RUBY_VERSION=3.2 docker-compose -f docker-compose-system-test.yml -f docker-compose.override.yml up& -RUBY_VERSION=3.2 docker-compose -f docker-compose-system-test.yml -f docker-compose.override.yml exec shell /bin/bash -``` - -(Sometimes, on shutdown, the Rails server PID file isn't removed, and so the above will fail. `rm demo/tmp/pids/server.pid` will fix it.) - -Once in the shell: - -```bash -cd demo -bundle exec rails test:system -``` - -Note that this system test approach is highly experimental and has some rough edges. The docker compose file and/or steps to run system tests may change. The tests currently fail, because the files with which they're being compared were generated on a Mac, but the Docker containers are running Linux. - -#### Simple Dockerfile - -This repository includes a `Dockerfile` to build an image with the minimum `bootstrap_form`-supported Ruby environment. To build the image: - -```bash -docker build --tag bootstrap_form . -``` - -This builds an image called `bootstrap_form`. You can change that to any tag you wish. Just make sure you use the same tag name in the `docker run` command. - -If you want to use a different Ruby version, or a smaller Linux distribution (although the distro may be missing tools you need): - -```bash -docker build --build-arg "RUBY_VERSION=3.0" --build-arg "DISTRO=slim-buster" --tag bootstrap_form . -``` - -Then run the container you built with the shell, and create the bundle: - -```bash -docker run --volume "$PWD:/app" --user $UID:`grep ^$USERNAME /etc/passwd | cut -d: -f4` -it bootstrap_form /bin/bash -bundle install -``` - -You can run tests in the container as normal, with `rake test`. - -(Some of that command line is need for Linux hosts, to run the container as the current user.) - -One of the disadvantages of this approach is that you can't release the gem from here, because the Docker container doesn't have access to your SSH credentials, or the right user name, or perhaps other things needed to release a gem. But for simple testing, it works. - -#### Troubleshooting Docker - -- With the above configuration, the gems are kept in `vendor/bundle` on your hosts, which is `$GEM_HOME` or `/app/vendor/bundle` in the running Docker container. If you're having permission problems when switching versions of Ruby or Rails, you can try `sudo rm -rf vendor/bundle` on the host, then run `BUNDLE_GEMFILES=gemfiles/7.0.gemfile bundle update` in the Docker container to re-install all the gems with the right permissions. +If you're intested in trying the Docker approach, read the [documentation](DOCKER.md). ### The Demo Application diff --git a/DOCKER.md b/DOCKER.md new file mode 100644 index 00000000..d8b88d03 --- /dev/null +++ b/DOCKER.md @@ -0,0 +1,75 @@ +# Working With Docker + +This repository offers experimental support support for developing using Docker, if you're interested. Docker is _not_ required to work on this gem. + +The `docker compose` approach should link to enough of your networking configuration that you can release the gem. +However, you have to do some of the configuration yourself, because it's dependent on your host operating system. + +## Set-Up + +Put your personal and OS-specific configuration in a `compose.override.yml` file. + +The following instructions work for an Ubuntu host, and will probably work for other common Linux distributions. Add a `compose.override.yml` in the local directory, that looks like this: + +```compose.override.yml +version: '3.3' + +# https://blog.giovannidemizio.eu/2021/05/24/how-to-set-user-and-group-in-docker compose/ + +services: + shell: + # You have to set the user and group for this process, because you're going to be + # creating all kinds of files from inside the container, that need to persist + # outside the container. + # Change `1000:1000` to the user and default group of your laptop user. + user: 1000:1000 + volumes: + - /etc/passwd:/etc/passwd:ro + - ~/.gem/credentials:/app/.gem/credentials:ro + # $HOME here is your host computer's `~`, e.g. `/home/reid`. + # `ssh` explicitly looks for its config in the home directory from `/etc/passwd`, + # so the target for this has to look like your home directory on the host. + - ~/.ssh:${HOME}/.ssh:ro + - ${SSH_AUTH_SOCK}:/ssh-agent + environment: + - SSH_AUTH_SOCK=/ssh-agent +``` + +You may have to change the `1000:1000` to the user and group IDs of your laptop. You may also have to change the `version` parameter to match the version of the `docker compose.yml` file. + +Adapting the above `compose.override.yml` for MacOS should be relatively straight-forward. Windows users, I'm afraid you're on your own. If you figure this out, a PR documenting how to do it would be most welcome. + +## Running + +Start the containers: + +```bash +docker compose up -d +``` + +You may need to install or update the gems: + +```bash +docker compose exec -it shell bundle install +``` + +To get a shell in the container: + +```bash +docker compose exec -it shell /bin/bash +``` + +Once in the shell: + +```bash +cd demo +bundle exec rails test:system +``` + +Note that this system test approach is highly experimental and has some rough edges. The docker compose file and/or steps to run system tests may change. The tests currently fail, because the files with which they're being compared were generated on a Mac, but the Docker containers are running Linux. + +## Troubleshooting Docker + +- With the above configuration, the gems are kept in `vendor/bundle` on your hosts, which is `$GEM_HOME` or `/app/vendor/bundle` in the running Docker container. If you're having permission problems when switching versions of Ruby or Rails, you can try `sudo rm -rf vendor/bundle` on the host, then run `BUNDLE_GEMFILES=gemfiles/7.0.gemfile bundle update` in the Docker container to re-install all the gems with the right permissions. +- Sometimes, on shutdown, the Rails server PID file isn't removed, and so the above will fail. `rm demo/tmp/pids/server.pid` will fix it. + diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 9a1e7589..00000000 --- a/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -ARG RUBY_VERSION=3.0 -ARG DISTRO=bullseye - -FROM ruby:$RUBY_VERSION-$DISTRO - -ARG NODE_MAJOR=18 - -RUN mkdir -p /app -ENV HOME /app -WORKDIR /app - -ENV GEM_HOME $HOME/vendor/bundle -ENV BUNDLE_APP_CONFIG="$GEM_HOME" -ENV PATH ./bin:$GEM_HOME/bin:$PATH -RUN (echo 'docker'; echo 'docker') | passwd root - -# Rails wants a newer version of node than we get with the Debian distro. -RUN curl -fsSL https://deb.nodesource.com/setup_$NODE_MAJOR.x | bash - && apt-get install -y nodejs -RUN corepack enable && corepack prepare yarn@stable --activate -RUN apt install -y -q sqlite3 - -EXPOSE 3000 diff --git a/docker-compose-system-test.yml b/compose.yml similarity index 57% rename from docker-compose-system-test.yml rename to compose.yml index 250fbe27..941dae2f 100644 --- a/docker-compose-system-test.yml +++ b/compose.yml @@ -1,34 +1,22 @@ -version: '3.3' - +# Set up the Selenium container based on the Selenium official: +# https://github.com/SeleniumHQ/docker-selenium/blob/trunk/docker-compose-v3.yml +# And: +# https://medium.com/@retrorubies/chrome-as-a-service-for-rails-testing-b1a45e70fec1 services: - app: &app - build: - context: . - args: - NODE_MAJOR: "12" - YARN_VERSION: "1.22.4" - RUBY_VERSION: ${RUBY_VERSION} - image: bootstrap-form:latest-$RUBY_VERSION - tmpfs: - - /tmp - shell: - <<: *app + image: lenchoreyes/jade:rails-app-3.0-sqlite-bullseye stdin_open: true tty: true volumes: - .:/app:cached environment: - - SSH_AUTH_SOCK=/ssh-agent - - NODE_ENV=development - - BOOTSNAP_CACHE_DIR=/usr/local/bundle/_bootsnap - - WEB_CONCURRENCY=1 - HISTFILE=/app/.bash_history - SELENIUM_HOST=selenium - SELENIUM_PORT=4444 - TEST_APP_HOST=shell - TEST_APP_PORT=3001 ports: + - "3000:3000" - "3001:3001" command: /bin/bash diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index fced7ad8..00000000 --- a/docker-compose.yml +++ /dev/null @@ -1,29 +0,0 @@ -version: '3.3' - -services: - app: &app - build: - context: . - args: - NODE_MAJOR: "18" - RUBY_VERSION: ${RUBY_VERSION} - image: bootstrap-form:latest-$RUBY_VERSION - tmpfs: - - /tmp - - shell: &shell - <<: *app - stdin_open: true - tty: true - volumes: - - .:/app:cached - environment: - - SSH_AUTH_SOCK=/ssh-agent - - NODE_ENV=development - - RAILS_ENV=${RAILS_ENV:-development} - - BOOTSNAP_CACHE_DIR=/usr/local/bundle/_bootsnap - - WEB_CONCURRENCY=1 - - HISTFILE=/app/.bash_history - ports: - - "3000:3000" - command: /bin/bash