Retrieve Artifactory BuildInfo timestamp properties - artifactory

I publish the BuildInfo to Artifactory using:
def buildInfo = Artifactory.newBuildInfo()
/* Set artifact properties */
buildInfo.env.capture = true
buildInfo.env.collect()
// Publish the build to Artifactory
server.upload spec: uploadSpec, buildInfo: buildInfo
I would like to retrieve the four property assigned to artifacts in Artifactory. I see properties being set such as build.name, build.number, build.timestamp, and vcs.revision
I can get the build number and name using:
def buildName = buildInfo.name
def buildNumber = buildInfo.number
How would I go about to retrieve the timestamp and vcs.number from the BuildInfo so that I can do a REST call and post the same four properties to a folder I create in Artifactory.

Timestamp in buildinfo is called started, as for vcs.number I assume you mean revision?

I installed Jenkins Build Timestamp Plugin and used this UTC pattern "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
In my groovy file, I added these two commands:
time=Date.parse("yyyy-MM-dd'T'HH:mm:ss.SSSZ", BUILD_TIMESTAMP)
epoch_milis = time.getTime()

Related

db.create_all() doesn't create a database in a desired directory

I am trying to create a database for my Flask application in the main directory of my project. This is my code for initializing a database:
app.config["SQLALCHEMY_DATABASE_URI"] = 'sqlite:///users.db'
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
Flask requires application context, so this is how I create the database:
$ flask shell
>>> db.create_all()
I also tried doing it with:
$ python
>>> from app import app, db
>>> app.app_context().push()
>>> db.create_all()
Both of these options create the database in the /instance directory. Is there any way to get around this and create it in the main directory of the project?
The instance path is the preferred and default location for the database. I recommend you to use this one for security reasons. However, it is also possible to choose an alternative solution in which the full length of the path is specified in the configuration.
The following configuration corresponds to an outdated variant, where the database is created in the current working directory. Please don't use this anymore.
app.config['SQLALCHEMY_DATABASE_URI'] ='sqlite:///' + os.path.join(os.getcwd(), 'users.db')
This corresponds to the current solution.
app.config['SQLALCHEMY_DATABASE_URI'] ='sqlite:///' + os.path.join(app.instance_path, 'users.db')

how does hydra manages timezone when it creates output directories?

I have a .yaml configuration file which looks like:
key: value
hydra:
run:
dir: ./data_fetcher/hydra_outputs/${now:%Y-%m-%d}/${now:%H-%M-%S}
with a python file main.py:
import hydra
#hydra.main(config_path="data_fetcher/config", config_name="config")
def main(cfg: DictConfig):
pass
if __name__ == "__main__":
main()
When running main.py an output directory is created according to the current date and time.
How does Hydra get the current time ? is it possible to change the timezone ?
Hydra is registering a simple OmegaConf custom resolver here with a line like:
register("now", lambda pattern: strftime(pattern, localtime()))
You can register your own custom resolver with a different name before #hydra.main() runs that will do what you want.
Read about custom resolvers in the OmegaConf documentation.
Read about how to get time in a different time zone here.
You can also file a feature request to add support for time zone to the ${now:...} custom resolve in Hydra. a PR would be appreciated.
For example, ${now:...} can support an optional second parameter for the time zone.

built.sbt without .repositories file with m2compatible set to true

i am in a scenario that the artifacts are published to a local maven repository with both both pom file and ivy file. I am trying to access this repository by treating it as an ivy repo, as a result, I had to set m2compatible=true so that the resolvers can correctly identify the path pattern.
sbt allows one to override the default list of resolvers through the following properties:
-Dsbt.override.build.repos=true -Dsbt.repository.config=<path to sbt repository file>
The foramt of the repository file is something like the following,
[repositories]
local
my-artifacts: http://my.artifact.proxyserver.com/artifacts/,[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]
maven : http://my.artifact.proxyserver.com/artifactory/maven-central
My question is how am I able to specify m2compatible=true for the resolver "my-artifacts" in the above file? Because without that setting, if I depend on
com.google.common % guava % 23.1
the resolver will look for the path:
com.google.common/guava/23.1
instead of
com/google/common/guava/23.1
sbt allows to add mavenCompatible towards the end of an ivy resolver.

Setting Logback Configuration file Programmatically

I'm using the sbt run command to run my project. My project uses the Logback logging mechanism and if I would like to enable logging, then I have to use the following command:
sbt -Dlogback.configurationFile=/path/to/log/file/app-logger.xml run
Is there a way that I could set this programmatically? I mean I would like to just say
sbt run
and it picks up automagically the app-logger.xml by itself via the application.
This is how I do it!
def loadLogger() = Option(System.getProperty("logback.configurationFile")) match {
case Some(logXml) =>
logger.info(s"using logger $logXml")
case None =>
val path = s"${System.getProperty("user.dir")}/conf/app-logger.xml"
System.setProperty("logback.configurationFile", path)
logger.info(s"using logger $path")
}

How to access a secured Nexus with sbt?

I'm trying to access a Nexus repository manager which requires some basic authentication. Everything works fine from Maven2 but when I try to configure things in SBT it can't find the artifacts. It is using a custom repository pattern (see this related question) but I don't think that should matter. In any case the relevant configuration is here.
Project.scala:
val snapshotsName = "Repository Snapshots"
val snapshotsUrl = new java.net.URL("http://nexusHostIp:8081/nexus/content/repositories/snapshots")
val snapshotsPattern = "[organisation]/[module]/[revision]-SNAPSHOT/[artifact]-[revision](-[timestamp]).[ext]"
val snapshots = Resolver.url(snapshotsName, snapshotsUrl)(Patterns(snapshotsPattern))
Credentials(Path.userHome / ".ivy2" / ".credentials", log)
val dep = "group" % "artifact" % "0.0.1" extra("timestamp" -> "20101202.195418-3")
~/.ivy2/.credentials:
realm=Snapshots Nexus
host=nexusHostIp:8081
user=nexususername
password=nexuspassword
According to a similar discussion in the SBT user group this should work fine but I am getting the following when I try to build.
==== Repository Snapshots: tried
[warn] -- artifact group#artifact;0.0.1!artifact.jar:
[warn] http://nexusHostIp:8081/nexus/content/repositories/snapshots/group/artifact/0.0.1-SNAPSHOT/artifact-0.0.1-20101202.195418-3.jar
I'm fairly certain this is a credentials problem and not something else because I can hit the URL it says it is trying directly and download the jar (after authenticating).
I have also tried declaring the credentials inline (even though it is less than ideal) like so:
Credentials.add("Repository Snapshots", "nexusHostIp", "nexususername", "nexuspassword")
Here's what I did (sbt 0.13 + artifactory - setup should be similar for nexus):
1) Edited the file ~/.sbt/repositories as specified here: http://www.scala-sbt.org/0.13.0/docs/Detailed-Topics/Proxy-Repositories.html
[repositories]
local
my-ivy-proxy-releases: http://repo.company.com/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
my-maven-proxy-releases: http://repo.company.com/maven-releases/
2) Locked down my artifactory to disable anonymous access.
3) Created a credentials file in ~/.sbt/.credentials
realm=Artifactory Realm
host=artifactory.mycompany.com
user=username
password=password
4) Created a file under ~/.sbt/0.13/plugins/credentials.sbt that wires up the default credentials
credentials += Credentials(Path.userHome / ".sbt" / ".credentials")
Now when my project loads sbt hits artifactory like normal.
The reason I did it this way is to keep the repository definitions, etc, out of the project files to enable teams to have flexibility (they can set up an internal server to serve in-progress artifacts, etc).
-Austen
UPDATE: This answer does not work in recent sbt versions - see Austen's answer instead.
Alright I finally got this sorted out.
snapshotsName can be anything. realm in .credentials must be the HTTP Authentication realm that shows up when trying to hit the URL of the repository (nexus in my case). realm is also the first parameter of Credentials.add. So that line should have been
Credentials.add("Sonatype Nexus Repository Manager", "nexusHostIp", "nexususername", "nexuspassword")
The host name is just the ip or DNS name. So in .credentials host is just nexusHostIp without the port number.
So the working Project configuration is:
val snapshotsName = "Repository Snapshots"
val snapshotsUrl = new java.net.URL("http://nexusHostIp:8081/nexus/content/repositories/snapshots")
val snapshotsPattern = "[organisation]/[module]/[revision]-SNAPSHOT/[artifact]-[revision](-[timestamp]).[ext]"
val snapshots = Resolver.url(snapshotsName, snapshotsUrl)(Patterns(snapshotsPattern))
Credentials(Path.userHome / ".ivy2" / ".credentials", log)
val dep = "group" % "artifact" % "0.0.1" extra("timestamp" -> "20101202.195418-3")
With a .credentials file that looks like:
realm=Sonatype Nexus Repository Manager
host=nexusHostIp
user=nexususername
password=nexuspassword
Where "Sonatype Nexus Repository Manager" is the HTTP Authentication realm.
Following the SBT Documetation:
There are two ways to specify credentials for such a repository:
Inline
credentials += Credentials("Some Nexus Repository Manager", "my.artifact.repo.net", "admin", "password123")
External File
credentials += Credentials(Path.userHome / ".ivy2" / ".credentials")
The .credentials file is a properties file with keys realm, host, user, and password. For example:
realm=Some Nexus Repository Manager
host=my.artifact.repo.net
user=admin
password=password123
If SBT launcher is failing to download a new version of SBT from your proxy, and that ~/.sbt/boot/update.log is showing that you're getting 401 authentication errors, you can use the environment variable SBT_CREDENTIALS to specify where the ivy credential file is.
Either of these should work and download the new sbt version:
SBT_CREDENTIALS='/home/YOUR_USER_NAME/.ivy2/.credentials' sbt
Putting export SBT_CREDENTIALS="/home/YOUR_USER_NAME/.ivy2/.credentials" in your .bashrc (or .zshrc), start a new shell session and then run sbt
(You'll need have the ~/.ivy2/.credentials file setup like other answers here has shown)
Source: https://github.com/sbt/sbt/commit/96e5a7957c830430f85b6b89d7bbe07824ebfc4b
This worked for me. I'm using SBT version 0.13.15:
~/.ivy2/.my-credentials (host without port):
realm=Sonatype Nexus Repository Manager
host=mynexus.mycompany.com
user=my_user
password=my_password
build.sbt (nexus url with port):
import sbt.Credentials
...
credentials += Credentials(Path.userHome / ".ivy2" / ".my-credentials")
...
resolvers in ThisBuild ++= Seq(
MavenRepository("my-company-nexus", "https://mynexus.mycompany.com:8081/repository/maven-releases/")
)
Check for all files containing credentials.
For me I had a new project in sbt 1.0 (instead of good old 0.13), where I had a ~/.sbt/1.0/global.sbt file containing my credentials, which I forgot about. So after a mandatory password change, the artifactory downloads was broken and locking my account.
Would be nice if the chain of credentials and files filling them can be easily inspected. Would also be nice if SBT was a bit more careful and first checking if authentication/authorization is correct, before starting tot download X files and locking my account after 3 misauthenticated attempts.

Resources