Skip to content

Commit

Permalink
namespace tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
jmarsh24 committed Aug 27, 2023
1 parent a30e606 commit bbd138e
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 108 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,16 +248,16 @@ config.middleware.use Shimmer::CloudflareProxy
Can't reproduce an issue with your local test data and just want the production or staging data on your development machine? Here you go:

```bash
rails db:pull
rails shimmer:db:pull
```

This will drop your local database and pull in the database of your connected Heroku app (make sure you executed `heroku git:remote -a your_app` before to have the git remote). But what about assets you might ask? Easy - assets are pulled from S3 as well via the AWS CLI automatically (make sure your environment variables in Heroku are correctly named as `AWS_REGION`, `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`) and the database is updated to use your local filesystem instead.

If you don't want the asset support, you can also only pull the database or only the assets:

```bash
rails db:pull_data
rails db:pull_assets
rails shimmer:db:pull_data
rails shimmer:db:pull_assets
```

### Localizable Routes with Browser Locale Support
Expand Down
32 changes: 17 additions & 15 deletions lib/shimmer/tasks/auth.rake
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
# frozen_string_literal: true

namespace :auth do
desc "Generates a Sign in with Apple Token"
task :apple_token do
ecdsa_key = OpenSSL::PKey::EC.new IO.read ".apple-key.p8"
headers = {
"kid" => Shimmer::Config.instance.apple_key_id!
}
claims = {
"iss" => Shimmer::Config.instance.apple_team_id!,
"iat" => Time.now.to_i,
"exp" => 180.days.from_now.to_i,
"aud" => "https://appleid.apple.com",
"sub" => Shimmer::Config.instance.apple_bundle_id!
}
puts JWT.encode claims, ecdsa_key, "ES256", headers
namespace :shimmer do
namespace :auth do
desc "Generates a Sign in with Apple Token"
task :apple_token do
ecdsa_key = OpenSSL::PKey::EC.new IO.read ".apple-key.p8"
headers = {
"kid" => Shimmer::Config.instance.apple_key_id!
}
claims = {
"iss" => Shimmer::Config.instance.apple_team_id!,
"iat" => Time.now.to_i,
"exp" => 180.days.from_now.to_i,
"aud" => "https://appleid.apple.com",
"sub" => Shimmer::Config.instance.apple_bundle_id!
}
puts JWT.encode claims, ecdsa_key, "ES256", headers
end
end
end
90 changes: 46 additions & 44 deletions lib/shimmer/tasks/db.rake
Original file line number Diff line number Diff line change
@@ -1,55 +1,57 @@
# frozen_string_literal: true

namespace :db do
desc "Downloads the app database from Heroku and imports it to the local database"
task pull_data: :environment do
config = if Rails.version.to_f >= 7
ActiveRecord::Base.connection_db_config.configuration_hash.with_indifferent_access
else
ActiveRecord::Base.connection_db_config.config
namespace :shimmer do
namespace :db do
desc "Downloads the app database from Heroku and imports it to the local database"
task pull_data: :environment do
config = if Rails.version.to_f >= 7
ActiveRecord::Base.connection_db_config.configuration_hash.with_indifferent_access
else
ActiveRecord::Base.connection_db_config.config
end
ENV["DISABLE_DATABASE_ENVIRONMENT_CHECK"] = "1"
Rake::Task["db:drop"].invoke
ENV["PGUSER"] = config["username"]
ENV["PGHOST"] = config["host"]
ENV["PGPORT"] = config["port"].to_s
sh "heroku pg:pull DATABASE_URL #{config["database"]}"
sh "rails db:environment:set"
sh "RAILS_ENV=test rails db:create"
end
ENV["DISABLE_DATABASE_ENVIRONMENT_CHECK"] = "1"
Rake::Task["db:drop"].invoke
ENV["PGUSER"] = config["username"]
ENV["PGHOST"] = config["host"]
ENV["PGPORT"] = config["port"].to_s
sh "heroku pg:pull DATABASE_URL #{config["database"]}"
sh "rails db:environment:set"
sh "RAILS_ENV=test rails db:create"
end

desc "Downloads the app assets from Heroku to directory `storage`."
task pull_assets: :environment do
config = JSON.parse(`heroku config --json`)
ENV["AWS_DEFAULT_REGION"] = config.fetch("AWS_REGION")
bucket = config.fetch("AWS_BUCKET")
ENV["AWS_ACCESS_KEY_ID"] = config.fetch("AWS_ACCESS_KEY_ID")
ENV["AWS_SECRET_ACCESS_KEY"] = config.fetch("AWS_SECRET_ACCESS_KEY")
storage_folder = Rails.root.join("storage")
download_folder = storage_folder.join("downloads")
FileUtils.mkdir_p download_folder
sh "aws s3 sync s3://#{bucket} #{storage_folder}/downloads"
download_folder.each_child do |file|
next if file.directory?
desc "Downloads the app assets from Heroku to directory `storage`."
task pull_assets: :environment do
config = JSON.parse(`heroku config --json`)
ENV["AWS_DEFAULT_REGION"] = config.fetch("AWS_REGION")
bucket = config.fetch("AWS_BUCKET")
ENV["AWS_ACCESS_KEY_ID"] = config.fetch("AWS_ACCESS_KEY_ID")
ENV["AWS_SECRET_ACCESS_KEY"] = config.fetch("AWS_SECRET_ACCESS_KEY")
storage_folder = Rails.root.join("storage")
download_folder = storage_folder.join("downloads")
FileUtils.mkdir_p download_folder
sh "aws s3 sync s3://#{bucket} #{storage_folder}/downloads"
download_folder.each_child do |file|
next if file.directory?

new_path = storage_folder.join file.basename.to_s.then { |e| [e[0..1], e[2..3], e] }.join("/")
FileUtils.mkdir_p(new_path.dirname)
FileUtils.cp(file, new_path)
new_path = storage_folder.join file.basename.to_s.then { |e| [e[0..1], e[2..3], e] }.join("/")
FileUtils.mkdir_p(new_path.dirname)
FileUtils.cp(file, new_path)
end
# purge variants
ActiveStorage::VariantRecord.delete_all
ActiveStorage::Blob.update_all(service_name: :local)
end
# purge variants
ActiveStorage::VariantRecord.delete_all
ActiveStorage::Blob.update_all(service_name: :local)
end

desc "Download all app data, including assets"
task pull: [:pull_data, :pull_assets]
desc "Download all app data, including assets"
task pull: [:pull_data, :pull_assets]

desc "Migrates if the database has any tables."
task migrate_if_tables: :environment do
if ActiveRecord::Base.connection.tables.any?
Rake::Task["db:migrate"].invoke
else
puts "No tables in database yet, skipping migration"
desc "Migrates if the database has any tables."
task migrate_if_tables: :environment do
if ActiveRecord::Base.connection.tables.any?
Rake::Task["db:migrate"].invoke
else
puts "No tables in database yet, skipping migration"
end
end
end
end
12 changes: 7 additions & 5 deletions lib/shimmer/tasks/lint.rake
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# frozen_string_literal: true

desc "Executes all linters and tests"
task :lint do
sh "bundle exec standardrb --fix"
sh "yarn lint"
sh "i18n-tasks health"
sh "bin/rspec"
namespace :shimmer do
task :lint do
sh "bundle exec standardrb --fix"
sh "yarn lint"
sh "i18n-tasks health"
sh "bin/rspec"
end
end
84 changes: 43 additions & 41 deletions lib/shimmer/tasks/s3.rake
Original file line number Diff line number Diff line change
@@ -1,46 +1,48 @@
# frozen_string_literal: true

namespace :s3 do
desc "Creates a new S3 bucket and outputs or uploads the credentials."
task :create_bucket do
puts "Please enter the name for your new bucket"
name = $stdin.gets.strip
region = "eu-central-1"
sh "aws s3 mb s3://#{name} --region #{region}"
sh "aws iam create-user --user-name #{name}"
policy = <<~JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:DeleteObject",
"s3:Put*",
"s3:Get*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::#{name}",
"arn:aws:s3:::#{name}/*"
]
}
]
}
JSON
File.write("policy.json", policy)
sh "aws iam put-user-policy --user-name #{name} --policy-name #{name} --policy-document file://policy.json"
File.delete("policy.json")
content = JSON.parse `aws iam create-access-key --user-name #{name}`
id = content.dig("AccessKey", "AccessKeyId")
secret = content.dig("AccessKey", "SecretAccessKey")
puts "Credentials and bucket were generated. Automatically assign them to the associated Heroku project? This will override and delete all current keys on Heroku. (y/n)"
vars = {AWS_REGION: region, AWS_BUCKET: name, AWS_ACCESS_KEY_ID: id, AWS_SECRET_ACCESS_KEY: secret}
if $stdin.gets.strip == "y"
sh "heroku config:set #{vars.map { |k, v| "#{k}=#{v}" }.join(" ")}"
else
vars.each { |k, v| puts "#{k}=#{v}" }
namespace :shimmer do
namespace :s3 do
desc "Creates a new S3 bucket and outputs or uploads the credentials."
task :create_bucket do
puts "Please enter the name for your new bucket"
name = $stdin.gets.strip
region = "eu-central-1"
sh "aws s3 mb s3://#{name} --region #{region}"
sh "aws iam create-user --user-name #{name}"
policy = <<~JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:DeleteObject",
"s3:Put*",
"s3:Get*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::#{name}",
"arn:aws:s3:::#{name}/*"
]
}
]
}
JSON
File.write("policy.json", policy)
sh "aws iam put-user-policy --user-name #{name} --policy-name #{name} --policy-document file://policy.json"
File.delete("policy.json")
content = JSON.parse `aws iam create-access-key --user-name #{name}`
id = content.dig("AccessKey", "AccessKeyId")
secret = content.dig("AccessKey", "SecretAccessKey")
puts "Credentials and bucket were generated. Automatically assign them to the associated Heroku project? This will override and delete all current keys on Heroku. (y/n)"
vars = {AWS_REGION: region, AWS_BUCKET: name, AWS_ACCESS_KEY_ID: id, AWS_SECRET_ACCESS_KEY: secret}
if $stdin.gets.strip == "y"
sh "heroku config:set #{vars.map { |k, v| "#{k}=#{v}" }.join(" ")}"
else
vars.each { |k, v| puts "#{k}=#{v}" }
end
end
end
end

0 comments on commit bbd138e

Please sign in to comment.